From e4e21c5fb87fd57466484c0c785f496b7e4f0940 Mon Sep 17 00:00:00 2001 From: Michael Date: Thu, 31 May 2018 13:37:09 +1000 Subject: [PATCH] Use KEY defines, add USB_HID keycodes For TouchPad.h, use #define KEYNAMES, support possible future change. Add USB_HID key definitions, and two functions pressU(), releaseU(). Supports a wider range of keys. Update KeyboardUK to support above functions. This compiles in Arduino IDE, but I don't have H/W to test. --- Touch_Pad_V4.1/KeyboardUK.h | 2 + Touch_Pad_V4.1/TouchPad.h | 2834 ++++++++++++++------------- Touch_Pad_V4.1/Touch_Pad_V4.1.ino | 3 + Touch_Pad_V4.1/USB_HID_Keycodes.cpp | 89 + Touch_Pad_V4.1/USB_HID_Keycodes.h | 405 ++++ 5 files changed, 1923 insertions(+), 1410 deletions(-) create mode 100644 Touch_Pad_V4.1/USB_HID_Keycodes.cpp create mode 100644 Touch_Pad_V4.1/USB_HID_Keycodes.h diff --git a/Touch_Pad_V4.1/KeyboardUK.h b/Touch_Pad_V4.1/KeyboardUK.h index 9363916..2a37d46 100644 --- a/Touch_Pad_V4.1/KeyboardUK.h +++ b/Touch_Pad_V4.1/KeyboardUK.h @@ -99,6 +99,8 @@ class Keyboard_ : public Print size_t write(uint8_t k); size_t press(uint8_t k); size_t release(uint8_t k); + size_t pressU(uint8_t k); + size_t releaseU(uint8_t k); void releaseAll(void); }; extern Keyboard_ Keyboard; diff --git a/Touch_Pad_V4.1/TouchPad.h b/Touch_Pad_V4.1/TouchPad.h index 4128876..b8c6476 100644 --- a/Touch_Pad_V4.1/TouchPad.h +++ b/Touch_Pad_V4.1/TouchPad.h @@ -1,1410 +1,1424 @@ -/******************************************************************************* - - MIT License - - Copyright (c) 2018, JacoBurge - - 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. - - ******************************************************************************* - - WARNING: Changing the code in this file could prevent your TouchPad from working! - - *******************************************************************************/ - -//Libraries: -#include -#include -#include - -//Compiler directives: -#define COMPATDELAY 1 //Defines increments in compatibility delay in mS -#define VIBRATE_LENGTH 38 //Defines number of interrupts motor will vibrate for, must be bigger than 8 for correct operation -#define SAFE_MODE //Disables OTG programming after first key press, comment out to disable -//#define RESET //Uncomment to reset EEPROM, upload, and then comment out again to prevent EEPROM being erased on every power cycle - -//Function definitions -bool touchDetection(); -void decodeArray(uint16_t dataIn, uint8_t *column, uint8_t *row); -void toggleKey(uint8_t key); -void GUI_keySelected(uint8_t column, uint8_t row); -void GUI_keyClear(); -void GUI_prog(); -void GUI_prog_leds(); -void GUI_menu(); -void GUI_clear_lines(uint8_t line); -void GUI_replace_lines(); -void GUI_replace_functions(uint8_t line); -void GUI_clear(); -void memoryKeyboard(uint16_t address, uint8_t stringLength, uint8_t printl); -void interruptSetup(); -ISR(TIMER1_COMPA_vect); -void pulseLED(); -uint8_t isTouchChangeDetected(); -uint8_t readDataFromTS(uint8_t reg); -uint8_t writeDataToTS(uint8_t reg, uint8_t data); -uint8_t checkTSPres(); -uint8_t capSetup(); -void touchClearCurrentDetections(); -uint16_t touchDetectionRoutine(); -void keyPress(int x, int y, int commandSet); - - -const uint8_t SENr[6] = {1, 2, 3, 5, 6, 7};//Maps capacitive pads to pins -const uint8_t SENc[6] = {0, 4, 8, 9, 10, 11}; - -volatile uint8_t LEDs[6][6];//Stores current LED values -volatile uint8_t col = 0;//Keeps track of current multiplex column for LEDs - -//Stores how to display each key in the 'On the go programmer' in flash -const uint8_t KEYS[100][5] PROGMEM = {" 0 ", " 1 ", " 2 ", " 3 ", " 4 ", " 5 ", " 6 ", " 7 ", " 8 ", " 9 ", - " a ", " b ", " c ", " d ", " e ", " f ", " g ", " h ", " i ", " j ", " k ", " l ", " m ", - " n ", " o ", " p ", " q ", " r ", " s ", " t ", " u ", " v ", " w ", " x ", " y ", " z ", - " F 1 ", " F 2 ", " F 3 ", " F 4 ", " F 5 ", " F 6 ", " F 7 ", " F 8 ", " F 9 ", " F10 ", " F11 ", " F12 ", - "L CTR", "L SHI", "L ALT", "L GUI", "PG UP", "R CTR", "R SHI", "R ALT", "R GUI", "PG DO", "LEFT ", " BSP ", - " ESC ", " HOM ", " UP ", "DOWN ", " TAB ", " INS ", " END ", "RIGHT", " RET ", " DEL ", "CAPS ", "SPACE", - " 1mS ", "10mS ", "100mS", " 1S ", " 5S ", " 10S ", " x2 ", " x3 ", " x4 ", " x5 ", " x10 ", " x20 " - }; - -//Stores ascii values for each keypress in flash -const uint8_t KEYS_PRESS[128] PROGMEM = {48, 49, 50, 51, 52, 53, 54, 55, 56, 57,//9 - 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109,//22 - 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122,//35 - 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205,//47 - 128, 129, 130, 131, 211, 132, 133, 134, 135, 214, 216, 178,//59 - 177, 210, 218, 217, 179, 209, 213, 215, 176, 212, 193, 32,//71(32) - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //83 - 35, 38, 64, 92, 47, 36, 37, 42, 43, 45, 60, 61, 62, 63, 59, 46, 33, //100 - 123, 125, 91, 93, 40, 41, 58, 44, 34, 39, 94, 95, 96, 124, 126, 30, 31 //117 - }; - -//Stores key locations for 'On the go programmer' menu in flash -const uint8_t KEYS_LOCATION[4][6][5] PROGMEM = {{{52, 51 , 50 , 49 , 48}, {57, 56 , 55 , 54 , 53}, {88, 87 , 86 , 85 , 84}, {61, 60 , 59 , 58 , 71}, {66, 65 , 64 , 63 , 62}, {70, 69 , 68 , 67 , 255}}, - {{34, 28 , 22 , 16 , 10}, {35, 29 , 23 , 17 , 11}, {97, 30 , 24 , 18 , 12}, {98, 31 , 25 , 19 , 13}, {99, 32 , 26 , 20 , 14}, {100, 33 , 27 , 21 , 15}}, - {{42, 36 , 91 , 6 , 0}, {43, 37 , 92 , 7 , 1}, {44, 38 , 93 , 8 , 2}, {45, 39 , 94 , 9 , 3}, {46, 40 , 95 , 89 , 4}, {47, 41 , 96 , 90 , 5}}, - {{113, 107 , 101 , 78 , 72}, {114, 108 , 102 , 79 , 73}, {115, 109 , 103 , 80 , 74}, {117 , 110 , 104 , 81 , 75}, {116, 111 , 105 , 82 , 76}, {255, 112 , 106 , 83 , 77}} -}; -//83 - -//Stores 'On the go programmer' strings in flash -const uint8_t STRINGS[43][50] PROGMEM = { - "/ / / * * * / / / /", - "/ L CTR / R CTR / # / SPACE / UP /RELEASE/", - "/ L SHI / R SHI / & / LEFT / DOWN / RIGHT /", - "/ L ALT / R ALT / @ / BSP / TAB / RET /", - "/ L GUI / R GUI / \\ / ESC / INS / DEL /", - "/ PG UP / PG DO / / / HOM / END / CAPS /", - "/ <- - / DEL / FUNCT / abc / F/123 / EXTRA /", - "- - - - - - - - - - - - - - - - - - - - - - - - -",//7 - "/ / / / / / /",//8 - "/ / / / * * * / / /",//9 - "/ a / b / c / d / e / f /", - "/ g / h / i / j / k / l /", - "/ m / n / o / p / q / r /", - "/ s / t / u / v / w / x /", - "/ y / z / ? / ; / . / ! /", - "/ / / / / * * * / /", - "/ 0 / 1 / 2 / 3 / 4 / 5 /", - "/ 6 / 7 / 8 / 9 / $ / % /", - "/ F 1 / F 2 / F 3 / F 4 / F 5 / F 6 /", - "/ F 7 / F 8 / F 9 / F10 / F11 / F12 /",//19 - "/ / / / / / * * * /", - "!!! Warning !!! When in the programming modes, ",//21 - "TouchPad takes control of your keyboard, this co ", - "uld EDIT or DELETE text or files if you leave thi", - "s window. !!! Warning !!! ",//24 - "Now in macro program mode, for command set ",//25 - "Use the following menus to assign keys on the key",//26 - "pad to macro keys for your program ",//27 - "Now in LED program mode, for command set ",//28 - "Touch LEDs to toggle them and swipe down when com",//29 - "plete ",//30 - "Programming complete, you can now close the notep", - "ad and safely resume work... ", - "No key selected. ",//33 - "Key ", - ", ", - " selected: ", - "/ 1mS / 10mS / 100mS / 1S / 5S / 10S /",//37 - "/ x2 / x3 / x4 / x5 / x10 / x20 /", - "/ * / + / - / < / = / > /",//39 - "/ { / } / [ / ] / ( / ) /", - "/ : / , / \" / ' / ^ / _ /", - "/ ` / | / ~ / "//42 -}; - -volatile enum GUI {NORMAL, PROG, PROG1, PROG_LEDS, PROG_LEDS1, CHANGE_MODE, NORMAL1, FACTORY} state;//State machine variable for UI -volatile uint32_t blinkerC = 0; //Timing for blinking LED -volatile uint8_t blinker = 0, blinkerD = 0; //Counter and direction for blinking LED -volatile uint8_t vibrate = 0; //Trigger vibration in interrupt -uint8_t progR = 10, progC = 10;//10 when no key selected, row and column when key selected -uint8_t GUI_Menu = 0;//Stores current GUI menu, 0 when none displayed, 1-4 for menus, 5 for clear - -int8_t currentMode = 0;//Stores current mode 0 - 4 -uint16_t compat = 0;//Compatibility mode off; -uint8_t setupEnable = 1;//No entering prog mode after first key press -uint8_t factoryTest[12];//Used for factory testing of keys - -//========================================================================================================= -//========================================================================================================= -// Setup -//========================================================================================================= -//========================================================================================================= - -void setup() { - Serial.begin(9600); - Wire.begin(); - Keyboard.begin(); - Mouse.begin(); - - pinMode(7, OUTPUT);//Motor enable - pinMode(6, OUTPUT);//Motor PWM - - pinMode(11, OUTPUT);//Power LED - - pinMode(A0, OUTPUT);//LEDs Columns - pinMode(A1, OUTPUT); - pinMode(A2, OUTPUT); - pinMode(A3, OUTPUT); - pinMode(A4, OUTPUT); - pinMode(A5, OUTPUT); - - pinMode(12, OUTPUT);//LEDs Rows - pinMode(8, OUTPUT); - pinMode(9, OUTPUT); - pinMode(10, OUTPUT); - pinMode(5, OUTPUT); - pinMode(13, OUTPUT); - - pinMode(0, INPUT);//Capacitive Interrupt - - if (EEPROM.read(1023) != 20) {//Setup EEPROM when first power up - digitalWrite(11, 1); - for (uint8_t j = 0; j < 5; j++) {//Setup EEPROM for default TouchPad - for (uint8_t i = 0; i < 180; i++) { - EEPROM.write((j * 200) + i, 255); - } - } - for (uint8_t j = 0; j < 5; j++) { - uint8_t i = 0; - for ( i = 180; i < 181 + j; i++) { - EEPROM.write((j * 200) + i, 1); - } - for ( i; i < 186; i++) { - EEPROM.write((j * 200) + i, 0); - } - } - EEPROM.write(1023, 20);//Setup complete - EEPROM.write(1022, 0);//Current Mode - EEPROM.write(1021, 20);//Factory Pass not complete - EEPROM.write(1020, 0); //Compat setting - - state = FACTORY; - for (int i = 0; i < 12; i++) {//All ones must be cleared to pass. set them here - factoryTest[i] = 1; - } - } - -#ifdef RESET - EEPROM.write(1023, 0);//Perform eeprom reset, setup will be performed on next power cycle -#endif - - if (EEPROM.read(1021) == 20) {//If factory test not complete, put it in this mode - state = FACTORY; - for (int i = 0; i < 12; i++) { - factoryTest[i] = 1; - } - } - -#ifdef ENABLE_MULTIPLE_COMMAND_SET - currentMode = EEPROM.read(1022);//Load current mode from EEPROM -#else - currentMode = 0; -#endif - - compat = EEPROM.read(1020);//Load compat setting from EEPROM - - if (currentMode > 4) {//Limit current mode to 0-5 - currentMode = 4; - } - else if (currentMode < 0) { - currentMode = 0; - } - - for (uint8_t i = 0; i < 6; i++) {//Clear all LEDs - for (uint8_t j = 0; j < 6; j++) { - LEDs[j][i] = 0; - } - } - - interruptSetup();//Setup LED matrix driver interrupt - - if (state != FACTORY) {//If not still in factory test - delay(2000); - digitalWrite(11, HIGH);//Light power LED briefly, signals calibrating - delay(100); - digitalWrite(11, LOW); - } - - capSetup();//Setup capacitive touch IC - writeDataToTS(0x06, 0x12);//Calibrate capacitive touch IC - - if (state != FACTORY) {//Set LEDs to match the current command set - delay(1000); - for (uint8_t i = 0; i < 6; i++) { - for (uint8_t j = 0; j < 6; j++) { - LEDs[j][i] = bitRead(EEPROM.read((currentMode * 200) + 180 + (j)), i);//Load values from EEPROM - } - } - } -} - -//========================================================================================================= -//========================================================================================================= -// Loop -//========================================================================================================= -//========================================================================================================= - -void loop() { - - switch (state) {//Main state machine for operation - case NORMAL: - touchDetection();//Run touchDetection - analogWrite(11, blinker);//Update LED - if (blinker < 255) { - if (millis() > blinkerC) { - analogWrite(11, blinker); - blinker++; - blinkerC = millis() + 1; - } - } - break; - case PROG: - touchDetection();//Run touchDetection - if (millis() > blinkerC) {//Update LED - analogWrite(11, blinker); - pulseLED(); - blinkerC = millis() + 4; - } - break; - case PROG_LEDS: - touchDetection();//Run touchDetection - if (millis() > blinkerC) {//Update LED - analogWrite(11, blinker); - pulseLED(); - blinkerC = millis() + 1; - } - break; - case FACTORY://Only occurs when EEPROM reset. - //Wait for all inputs to be tested - if (factoryTest[0] + factoryTest[1] + factoryTest[2] + factoryTest[3] + factoryTest[4] + factoryTest[5] + factoryTest[6] + factoryTest[7] + factoryTest[8] + factoryTest[9] + factoryTest[10] + factoryTest[11] > 0) { - touchDetection();//Run touchDetection - if (millis() > blinkerC) { - digitalWrite(11, !digitalRead(11)); - blinkerC = millis() + 300; - } - } - else {//Test all LEDs - for (uint8_t i = 0; i < 6; i++) { - for (uint8_t j = 0; j < 6; j++) { - LEDs[j][i] = 0; - } - } - for (uint8_t i = 0; i < 6; i++) { - for (uint8_t j = 0; j < 6; j++) { - LEDs[j][i] = 1; - } - delay(200); - for (uint8_t j = 0; j < 6; j++) { - LEDs[j][i] = 0; - } - } - for (uint8_t i = 0; i < 6; i++) { - for (uint8_t j = 0; j < 6; j++) { - LEDs[i][j] = 1; - } - delay(200); - for (uint8_t j = 0; j < 6; j++) { - LEDs[i][j] = 0; - } - } - for (uint8_t i = 0; i < 6; i++) {//Load current LED pattern - for (uint8_t j = 0; j < 6; j++) { - LEDs[j][i] = bitRead(EEPROM.read((currentMode * 200) + 180 + (j)), i); - } - } - state = NORMAL;//Enter normal operation - EEPROM.write(1021, 0);//Set factory test pass - } - break; - } -} - -//========================================================================================================= -//========================================================================================================= -// Check capacitive array - Returns 1 for positive ID, 0 for negative ID -//========================================================================================================= -//========================================================================================================= - -bool touchDetection() { - if (isTouchChangeDetected()) { - uint16_t dataIn, row = 10, column = 10; - dataIn = touchDetectionRoutine(); - if ((dataIn & 0b111100010001) > 0 && (dataIn & 0b000011101110) > 0) { - uint8_t column, row; - decodeArray(dataIn, &column, &row); - - if (column != 10 && row != 10) { - vibrate = VIBRATE_LENGTH;//Trigger vibration - - LEDs[column][row] = 1; - dataIn = touchDetectionRoutine(); - while ((dataIn & (0b1 << SENr[row])) > 0 || (dataIn & (0b1 << SENc[column])) > 0) { - dataIn = touchDetectionRoutine(); -#ifdef ENABLE_MULTIPLE_COMMAND_SET//disable multipe command sets - //Horizontal swipe detect - if ((dataIn & (0b1 << SENr[row])) > 0 && (dataIn & (0b1 << SENc[column])) == 0 && (dataIn & 0b111100010001) > 0 && state == NORMAL) { - uint8_t columnNew, rowNew; - decodeArray(dataIn, &columnNew, &rowNew); - - if (columnNew > column) { - //===============================================================================================Swipe Right... - for (uint8_t i = column; i < 6; i++) { - LEDs[i][row] = 1; - delay(50); - } - currentMode--; - if (currentMode < 0) { - currentMode = 4; - } - EEPROM.write(1022, currentMode); - //Keyboard.println(currentMode); - - digitalWrite(7, HIGH); - analogWrite(6, 180); - for (int8_t i = 6; i >= 0; i--) {//Change - if (i < 4) { - analogWrite(6, 127); - digitalWrite(7, LOW); - } - for (uint8_t j = 0; j < 6; j++) { - for (uint8_t k = 0; k < 6; k++) { - LEDs[j][k] = 0; - if (j - i >= 0) { - LEDs[j - i][k] = bitRead(EEPROM.read((currentMode * 200) + 180 + (j)), k); - } - } - } - delay(100); - } - - state = CHANGE_MODE; - - //===============================================================================================...Swipe Right - } - else { - //===============================================================================================Swipe Left... - for (int8_t i = column; i >= 0; i--) { - LEDs[i][row] = 1; - delay(50); - } - - currentMode++; - if (currentMode > 4) { - currentMode = 0; - } - EEPROM.write(1022, currentMode); - //Keyboard.println(currentMode); - - digitalWrite(7, HIGH); - analogWrite(6, 180); - for (int8_t i = 6; i >= 0; i--) {//Change - if (i < 4) { - analogWrite(6, 127); - digitalWrite(7, LOW); - } - for (uint8_t j = 0; j < 6; j++) { - for (uint8_t k = 0; k < 6; k++) { - LEDs[j][k] = 0; - } - } - for (uint8_t j = 0; j < 6; j++) { - for (uint8_t k = 0; k < 6; k++) { - if (j + i <= 5 ) { - LEDs[j + i][k] = bitRead(EEPROM.read((currentMode * 200) + 180 + (j)), k); - } - } - } - delay(100); - } - state = CHANGE_MODE; - - //===============================================================================================...Swipe Left - } - - while ((dataIn & (0b1 << SENr[row])) > 0 || (dataIn & (0b1 << SENc[column])) > 0) { - dataIn = touchDetectionRoutine(); - } - break; - } -#endif -#ifdef ENABLE_OTG_PROGRAMMER - //Vertical swipe detect - if ((dataIn & (0b1 << SENc[column])) > 0 && (dataIn & (0b1 << SENr[row])) == 0 && (dataIn & 0b000011101110) > 0) { - uint8_t columnNew, rowNew; - decodeArray(dataIn, &columnNew, &rowNew); - if (rowNew > row) { - //===============================================================================================Swipe Up... - - if (state == NORMAL) { - if (setupEnable == 1) {//Only enter setup mode immediately after power up! - for (uint8_t i = row; i < 6; i++) { - LEDs[column][i] = 1; - delay(50); - } - - digitalWrite(7, HIGH); - analogWrite(6, 180); - for (int8_t i = 6; i >= 0; i--) { - for (uint8_t j = 0; j < 6; j++) { - for (uint8_t k = 0; k < 6; k++) { - LEDs[j][k] = 0; - if (k - i >= 0) { - LEDs[j][k - i] = bitRead(EEPROM.read((currentMode * 200) + 180 + (j)), k); - } - } - } - delay(100); - } - analogWrite(6, 127); - digitalWrite(7, LOW); - state = PROG_LEDS1; - } - } - else if (state == PROG) { - digitalWrite(7, HIGH); - analogWrite(6, 180); - for (uint8_t i = row; i < 6; i++) { - LEDs[column][i] = 1; - delay(100); - } - analogWrite(6, 127); - digitalWrite(7, LOW); - state = NORMAL1; - GUI_clear(); - } - - //===============================================================================================...Swipe Up - } - else { - //===============================================================================================Swipe Down... - if (state == NORMAL) { - if (setupEnable == 1) {//Only enter setup mode immediately after power up! - digitalWrite(7, HIGH); - analogWrite(6, 180); - for (int8_t i = row; i >= 0; i--) { - LEDs[column][i] = 1; - delay(100); - } - analogWrite(6, 127); - digitalWrite(7, LOW); - state = PROG1; - - } - } - else if (state == PROG) { - digitalWrite(7, HIGH); - analogWrite(6, 180); - for (int8_t i = row; i >= 0; i--) { - LEDs[column][i] = 1; - delay(100); - } - analogWrite(6, 127); - digitalWrite(7, LOW); - Keyboard.releaseAll(); - compat += COMPATDELAY; - EEPROM.write(1020, compat); - GUI_clear(); - Keyboard.press(129);//Shift - for (uint8_t i = 0; i < 3; i++) { - toggleKey(218);//Up - } - Keyboard.release(129);//Shift - toggleKey(178);//Backspace - state = PROG1; - } - - else if (state == PROG_LEDS) { - - for (int8_t i = row; i >= 0; i--) { - LEDs[column][i] = 1; - delay(50); - } - digitalWrite(7, HIGH); - analogWrite(6, 180); - for (uint8_t i = 0; i <= 6; i++) { - - - - for (uint8_t j = 0; j < 6; j++) { - for (uint8_t k = 0; k < 6; k++) { - LEDs[j][k] = 0; - if (k - i >= 0) { - LEDs[j][k - i] = bitRead(EEPROM.read((currentMode * 200) + 180 + (j)), k); - } - } - } - delay(100); - } - analogWrite(6, 127); - digitalWrite(7, LOW); - state = NORMAL1; - GUI_clear(); - } - //===============================================================================================...Swipe Down - - } - - while ((dataIn & (0b1 << SENr[row])) > 0 || (dataIn & (0b1 << SENc[column])) > 0) { - dataIn = touchDetectionRoutine(); - } - break; - } -#endif - //===============================================================================================While Pressed... - - - //===============================================================================================...While Pressed - } - touchClearCurrentDetections(); - - //===============================================================================================When Released... - uint8_t repeat[5] = {0, 0, 0, 0, 0}; - switch (state) { - case CHANGE_MODE: - state = NORMAL; - break; - case FACTORY: - factoryTest[row] = 0; - factoryTest[6 + column] = 0; - break; - case NORMAL: - if (setupEnable == 1) { -#ifdef SAFE_MODE - setupEnable = 0; -#endif - } - for (uint8_t i = 0; i < 6; i++) { - for (uint8_t j = 0; j < 6; j++) { - LEDs[i][j] = 0; - } - } - - for (int i = 0; i < 5; i++) { -#ifdef ENABLE_OTG_PROGRAMMER - uint8_t temp = EEPROM.read((currentMode * 200) + (column * 30) + (row * 5) + i); - if (temp != 255) { - if (((temp & 0b01111111) < 72) || ((temp & 0b01111111) > 83)) { - uint8_t key = pgm_read_byte(&(KEYS_PRESS[temp & 0b01111111])); - Keyboard.press(key); - if (temp > 127) { - Keyboard.releaseAll(); - } - } - else if (((temp & 0b01111111) >= 72 ) && ((temp & 0b01111111) <= 77)) { - switch (temp & 0b01111111) { - case 72: delay(1); break; - case 73: delay(10); break; - case 74: delay(100); break; - case 75: delay(1000); break; - case 76: delay(5000); break; - case 77: delay(10000); break; - - } - } - else { - if (repeat[i] > 0) { - repeat[i]--; - if (repeat[i] > 0) { - i = -1; - } - } - else { - switch (temp & 0b01111111) { - case 78: repeat[i] = 1; break; - case 79: repeat[i] = 2; break; - case 80: repeat[i] = 3; break; - case 81: repeat[i] = 4; break; - case 82: repeat[i] = 9; break; - case 83: repeat[i] = 19; break; - - } - i = -1; - } - } - } - else { -#endif - if (i == 0) { - keyPress(column, row, currentMode + 1); //If key not programmed, default to info stored in flash (KeyDefinitions.h) - } - break; -#ifdef ENABLE_OTG_PROGRAMMER - } -#endif - } -#ifdef ENABLE_DEFAULT_RELEASE - Keyboard.releaseAll(); -#endif - - break; - case NORMAL1: - for (uint8_t i = 0; i < 6; i++) { - for (uint8_t j = 0; j < 6; j++) { - LEDs[i][j] = 0; - } - } - state = NORMAL; - break; - case PROG1: - for (uint8_t i = 0; i < 6; i++) { - for (uint8_t j = 0; j < 6; j++) { - LEDs[i][j] = 0; - } - } - if (compat > 0) { - Keyboard.print("Compatibility level: "); - Keyboard.print(compat / COMPATDELAY); - Keyboard.releaseAll(); - } - GUI_prog(); - state = PROG; - progR = 10; - progC = 10; - GUI_Menu = 0; - GUI_keySelected(progC, progR); - GUI_menu(); - GUI_Menu = 6; - break; - case PROG: - for (uint8_t i = 0; i < 6; i++) { - for (uint8_t j = 0; j < 6; j++) { - LEDs[i][j] = 0; - } - } - - if (progC != 10 || progR != 10) { - LEDs[progC][progR] = 1; - } - - if (progC == 10 || progR == 10) { - progC = column; - progR = row; - LEDs[progC][progR] = 1; - GUI_keyClear(); - GUI_menu(); - GUI_Menu = 1; - } - else if (column == 0 && row == 5) { - LEDs[progC][progR] = 0; - progC = 10; - progR = 10; - GUI_keyClear(); - GUI_Menu = 5; - GUI_menu(); - } - else if (column == 1 && row == 5 ) { - for (uint8_t i = 0; i < 4; i++) { - if (EEPROM.read((currentMode * 200) + (progC * 30) + (progR * 5) + (i + 1)) == 255) { - EEPROM.write((currentMode * 200) + (progC * 30) + (progR * 5) + (i), 255); - } - } - if (EEPROM.read((currentMode * 200) + (progC * 30) + (progR * 5) + (4)) != 255) { - EEPROM.write((currentMode * 200) + (progC * 30) + (progR * 5) + (4), 255); - } - GUI_keyClear(); - } - else if (column == 2 && row == 5 && GUI_Menu != 1) { - GUI_Menu = 1; - GUI_menu(); - } - else if (column == 3 && row == 5 && GUI_Menu != 2) { - GUI_Menu = 2; - GUI_menu(); - } - else if (column == 4 && row == 5 && GUI_Menu != 3) { - GUI_Menu = 3; - GUI_menu(); - } - else if (column == 5 && row == 5 && GUI_Menu != 4) { - GUI_Menu = 4; - GUI_menu(); - } - else if (column == 5 && row == 0 && GUI_Menu == 4) { - compat = 0; - EEPROM.write(1020, compat); - } - else if (column == 5 && row == 4 && GUI_Menu == 1 ) {//Release - for (uint8_t i = 1; i < 6; i++) { - if (EEPROM.read((currentMode * 200) + (progC * 30) + (progR * 5) + (i)) == 255 || i == 5) { - uint8_t temp = EEPROM.read((currentMode * 200) + (progC * 30) + (progR * 5) + (i - 1)); - if (temp != 255) { - if (((temp & 0b01111111) < 72) || ((temp & 0b01111111) > 83) ) { - if (temp > 127) { - EEPROM.write((currentMode * 200) + (progC * 30) + (progR * 5) + (i - 1), temp & 127); - } - else { - EEPROM.write((currentMode * 200) + (progC * 30) + (progR * 5) + (i - 1), temp | 128); - } - } - GUI_keyClear(); - } - break; - } - } - - } - else if (row < 5 && pgm_read_byte(&(KEYS_LOCATION[GUI_Menu - 1][column][row])) != 255 && GUI_Menu > 0 && GUI_Menu < 5) { - for (uint8_t i = 0; i < 5; i++) { - if (EEPROM.read((currentMode * 200) + (progC * 30) + (progR * 5) + (i)) == 255) { - EEPROM.write((currentMode * 200) + (progC * 30) + (progR * 5) + (i), pgm_read_byte(&(KEYS_LOCATION[GUI_Menu - 1][column][row]))); - break; - } - } - GUI_keyClear(); - } - break; - case PROG_LEDS1: - for (uint8_t i = 0; i < 6; i++) { - for (uint8_t j = 0; j < 6; j++) { - LEDs[i][j] = bitRead(EEPROM.read((currentMode * 200) + 180 + (i)), j); - } - } - GUI_prog_leds(); - state = PROG_LEDS; - break; - case PROG_LEDS: - if (row > 0) { - uint8_t temp = EEPROM.read((currentMode * 200) + 180 + (column)); - bitWrite(temp, row, !bitRead(temp, row)); - EEPROM.write((currentMode * 200) + 180 + (column), temp); - } - for (uint8_t i = 0; i < 6; i++) { - for (uint8_t j = 0; j < 6; j++) { - LEDs[i][j] = bitRead(EEPROM.read((currentMode * 200) + 180 + (i)), j); - } - } - break; - - } - //===============================================================================================...When Released - return 1; - } - } - else { - touchClearCurrentDetections(); - } - } - return 0; -} - -//Process raw capacitive data, map pins to rows and columns -void decodeArray(uint16_t dataIn, uint8_t *column, uint8_t *row) { - uint8_t i1 = 20, i2 = 20; - for (uint8_t i = 0; i < 12; i++) { - if ((dataIn & 0b1) == 1) { - if (i1 == 20) { - i1 = i; - } - else if (i2 == 20) { - i2 = i; - } - } - dataIn = dataIn >> 1; - } - - for (uint8_t j = 0; j < 6; j++) { - if (SENr[j] == i1 || SENr[j] == i2) { - *row = j; - } - if (SENc[j] == i1 || SENc[j] == i2) { - *column = j; - } - } -} - -//========================================================================================================= -//========================================================================================================= -// GUI Functions -//========================================================================================================= -//========================================================================================================= - -//Press key on keyboard, perform compat delay -void toggleKey(uint8_t key) { - Keyboard.press(key); - Keyboard.release(key); - if (compat > 0) { - delay(compat); - } -} - -//Update current key selection list -void GUI_keySelected(uint8_t column, uint8_t row) { - if (column == 10 || row == 10) { - memoryKeyboard(33, 49, 0); - } - else { - memoryKeyboard(34, 4, 0); - Keyboard.print(column); - memoryKeyboard(35, 1, 0); - Keyboard.print(row); - memoryKeyboard(36, 11, 0); - for (uint8_t i = 0; i < 5; i++) { - uint8_t temp1 = EEPROM.read((currentMode * 200) + (column * 30) + (row * 5) + (i)); - if (temp1 != 255) { - toggleKey(91); - if ((temp1 & 0b01111111) < 84) { - for (uint8_t j = 0; j < 5; j++) { - toggleKey(pgm_read_byte(&(KEYS[temp1 & 0b01111111][j]))); - } - } - else { - toggleKey(32); - toggleKey(32); - toggleKey(pgm_read_byte(&(KEYS_PRESS[temp1 & 0b01111111]))); - toggleKey(32); - toggleKey(32); - } - toggleKey(93); - if (temp1 > 127) { - toggleKey(114); - } - else { - toggleKey(32); - } - } - else { - for (uint8_t j = 0; j < (8 * (5 - i)); j++) { - toggleKey(32); - } - break; - } - } - } - toggleKey(176); //Return - toggleKey(176); //Return - Keyboard.releaseAll(); -} - -//Clear current key selection -void GUI_keyClear() { - for (uint8_t i = 0; i < 26; i++) { - toggleKey(218);//Up - } - toggleKey(217);//Down - toggleKey(216);//Left - - Keyboard.press(129);//Shift - Keyboard.press(218);//Up - Keyboard.releaseAll(); - toggleKey(178);//Backspace - toggleKey(176);//Return - GUI_keySelected(progC, progR); - toggleKey(178);//Backspace - toggleKey(178);//Backspace - for (uint8_t i = 0; i < 26; i++) { - toggleKey(217);//Down - } - toggleKey(216);//Left - toggleKey(217);//Down - Keyboard.releaseAll(); -} - -//Type basic prog interface -void GUI_prog() { - toggleKey(176); //Return - toggleKey(176); //Return - memoryKeyboard(21, 49, 0); - memoryKeyboard(22, 48, 0); - memoryKeyboard(23, 49, 0); - memoryKeyboard(24, 27, 0); - toggleKey(176); //Return - toggleKey(176); //Return - memoryKeyboard(25, 43, 0); - Keyboard.print((currentMode + 1)); - toggleKey(176); //Return - toggleKey(176); //Return - memoryKeyboard(26, 49, 0); - memoryKeyboard(27, 34, 0); - toggleKey(176); //Return - toggleKey(176); //Return - Keyboard.releaseAll(); -} - -//Type basic LED prog interface -void GUI_prog_leds() { - toggleKey(176); //Return - toggleKey(176); //Return - memoryKeyboard(21, 49, 0); - memoryKeyboard(22, 48, 0); - memoryKeyboard(23, 49, 0); - memoryKeyboard(24, 27, 0); - toggleKey(176); //Return - toggleKey(176); //Return - memoryKeyboard(28, 41, 0); - Keyboard.print((currentMode + 1 )); - toggleKey(176); //Return - toggleKey(176); //Return - memoryKeyboard(29, 49, 0); - memoryKeyboard(30, 5, 0); - Keyboard.releaseAll(); -} - -//Manage typing and clearing GUI menus for prog interface -void GUI_menu() { - toggleKey(215); - switch (GUI_Menu) { - case 0: - for (uint8_t i = 0; i < 6; i++) { - memoryKeyboard(7, 49, 1); - memoryKeyboard(8, 49, 1); - memoryKeyboard(8, 49, 1); - memoryKeyboard(8, 49, 1); - } - memoryKeyboard(7, 49, 0); - GUI_Menu = 1; - break; - case 1: - for (uint8_t i = 0; i < 21; i++) { - toggleKey(218);//Up - } - GUI_replace_lines(); - memoryKeyboard(0, 49, 0); - GUI_replace_functions(3); - memoryKeyboard(1, 49, 0); - GUI_replace_functions(4); - memoryKeyboard(2, 49, 0); - GUI_replace_functions(4); - memoryKeyboard(3, 49, 0); - GUI_replace_functions(4); - memoryKeyboard(4, 49, 0); - GUI_replace_functions(4); - memoryKeyboard(5, 49, 0); - toggleKey(217);//Down - toggleKey(217);//Down - break; - case 2: - for (uint8_t i = 0; i < 21; i++) { - toggleKey(218);//Up - } - GUI_replace_lines(); - memoryKeyboard(9, 49, 0); - GUI_replace_functions(3); - memoryKeyboard(10, 49, 0); - GUI_replace_functions(4); - memoryKeyboard(11, 49, 0); - GUI_replace_functions(4); - memoryKeyboard(12, 49, 0); - GUI_replace_functions(4); - memoryKeyboard(13, 49, 0); - GUI_replace_functions(4); - memoryKeyboard(14, 49, 0); - toggleKey(217);//Down - toggleKey(217);//Down - break; - case 3: - for (uint8_t i = 0; i < 21; i++) { - toggleKey(218);//Up - } - GUI_replace_lines(); - memoryKeyboard(15, 49, 0); - GUI_replace_functions(3); - memoryKeyboard(16, 49, 0); - GUI_replace_functions(4); - memoryKeyboard(17, 49, 0); - GUI_replace_functions(4); - memoryKeyboard(39, 49, 0); - GUI_replace_functions(4); - memoryKeyboard(18, 49, 0); - GUI_replace_functions(4); - memoryKeyboard(19, 49, 0); - toggleKey(217);//Down - toggleKey(217);//Down - break; - case 4: - for (uint8_t i = 0; i < 21; i++) { - toggleKey(218);//Up - } - GUI_replace_lines(); - memoryKeyboard(20, 49, 0); - GUI_replace_functions(3); - memoryKeyboard(37, 49, 0); - GUI_replace_functions(4); - memoryKeyboard(38, 49, 0); - GUI_replace_functions(4); - memoryKeyboard(40, 49, 0); - GUI_replace_functions(4); - memoryKeyboard(41, 49, 0); - GUI_replace_functions(4); - memoryKeyboard(42, 28, 0); - toggleKey(31); - Keyboard.print(" / "); - toggleKey(30); - Keyboard.print(" / R C /"); - toggleKey(217);//Down - toggleKey(217);//Down - break; - case 5: - - for (uint8_t i = 0; i < 22; i++) { - toggleKey(218);//Up - } - GUI_replace_lines(); - memoryKeyboard(8, 49, 0); - GUI_replace_functions(1); - memoryKeyboard(8, 49, 0); - GUI_replace_functions(3); - memoryKeyboard(8, 49, 0); - GUI_replace_functions(4); - memoryKeyboard(8, 49, 0); - GUI_replace_functions(4); - memoryKeyboard(8, 49, 0); - GUI_replace_functions(4); - memoryKeyboard(8, 49, 0); - GUI_replace_functions(4); - memoryKeyboard(8, 49, 0); - toggleKey(217);//Down - toggleKey(217);//Down - GUI_Menu = 6; - break; - case 6: - for (uint8_t i = 0; i < 22; i++) { - toggleKey(218);//Up - } - GUI_replace_lines(); - memoryKeyboard(6, 49, 0); - GUI_replace_functions(1); - memoryKeyboard(0, 49, 0); - GUI_replace_functions(3); - memoryKeyboard(1, 49, 0); - GUI_replace_functions(4); - memoryKeyboard(2, 49, 0); - GUI_replace_functions(4); - memoryKeyboard(3, 49, 0); - GUI_replace_functions(4); - memoryKeyboard(4, 49, 0); - GUI_replace_functions(4); - memoryKeyboard(5, 49, 0); - toggleKey(217);//Down - toggleKey(217);//Down - break; - } - Keyboard.releaseAll(); -} - -//Clear x number lines above cursor position -void GUI_clear_lines(uint8_t line) { - Keyboard.press(129);//Shift - for (uint8_t i = 0; i < line; i++) { - toggleKey(218);//Up - } - Keyboard.release(129);//Shift - toggleKey(178);//Backspace -} - -//Delete single line left of cursor -void GUI_replace_lines() { - Keyboard.press(129);//Shift - toggleKey(218);//Up - Keyboard.release(129);//Shift - toggleKey(176); //Return -} - -//Scroll down and call replace line -void GUI_replace_functions(uint8_t line) { - for (uint8_t i = 0; i < line; i++) { - toggleKey(217);//Down - } - GUI_replace_lines(); -} - -//Delete all and type prog done message -void GUI_clear() { - Keyboard.press(129);//Shift - for (uint8_t i = 0; i < 35; i++) { - toggleKey(218);//Up - } - Keyboard.release(129);//Shift - toggleKey(178);//Backspace - toggleKey(176); //Return - Keyboard.releaseAll(); - memoryKeyboard(31, 49, 0); - memoryKeyboard(32, 28, 0); - //Keyboard.println(""); - Keyboard.releaseAll(); -} - -//Type data from program memory -void memoryKeyboard(uint16_t address, uint8_t stringLength, uint8_t printl) { - - for (uint8_t j = 0; j < stringLength; j++) { - toggleKey(pgm_read_byte(&(STRINGS[address][j]))); - } - if (printl == 1) { - toggleKey(176); //Return - } -} - -//========================================================================================================= -//========================================================================================================= -// LED Display Functions -//========================================================================================================= -//========================================================================================================= - -//Setup interrupt to handle LEDs -void interruptSetup() { - cli(); // disable global interrupts - TCCR1A = 0; // set entire TCCR1A register to 0 - TCCR1B = 0; // same for TCCR1B - // set compare match register to desired timer count - OCR1A = 10; - // turn on CTC mode: - TCCR1B |= (1 << WGM12); - // Set CS10 and CS12 bits for 1024 prescaler - TCCR1B |= (1 << CS10); - TCCR1B |= (1 << CS12); - // enable timer compare interrupt - TIMSK1 |= (1 << OCIE1A); - // enable global interrupts - TCNT1 = 0; - sei(); -} - -//LED driving interrupt -ISR(TIMER1_COMPA_vect) { - - for (uint8_t c = 0; c < 6; c ++) { - switch (c) { - case 0: digitalWrite(12, 0); break; - case 1: digitalWrite(8, 0); break; - case 2: digitalWrite(9, 0); break; - case 3: digitalWrite(10, 0); break; - case 4: digitalWrite(5, 0); break; - case 5: digitalWrite(13, 0); break; - } - } - - switch (col) { - case 0: digitalWrite(A0, 1); break; - case 1: digitalWrite(A2, 1); break; - case 2: digitalWrite(A3, 1); break; - case 3: digitalWrite(A4, 1); break; - case 4: digitalWrite(A5, 1); break; - case 5: digitalWrite(A1, 1); break; - } - - switch (col) { - case 0: digitalWrite(A2, 0); break; - case 1: digitalWrite(A3, 0); break; - case 2: digitalWrite(A4, 0); break; - case 3: digitalWrite(A5, 0); break; - case 4: digitalWrite(A1, 0); break; - case 5: digitalWrite(A0, 0); break; - } - - for (uint8_t c = 0; c < 6; c ++) { - switch (c) { - case 0: digitalWrite(12, LEDs[col][c]); break; - case 1: digitalWrite(8, LEDs[col][c]); break; - case 2: digitalWrite(9, LEDs[col][c]); break; - case 3: digitalWrite(10, LEDs[col][c]); break; - case 4: digitalWrite(5, LEDs[col][c]); break; - case 5: digitalWrite(13, LEDs[col][c]); break; - } - } - - col++; - if (col > 5) { - col = 0; - } - - if (vibrate == VIBRATE_LENGTH) { - digitalWrite(7, HIGH); - analogWrite(6, 255); - vibrate--; - } - else if (vibrate == 8) { - analogWrite(6, 0); - vibrate--; - } - else if (vibrate == 1) { - analogWrite(6, 127); - digitalWrite(7, LOW); - vibrate--; - } - else if (vibrate > 0) { - vibrate--; - } -} - -//Handle power LED fades -void pulseLED() { - if (blinkerD == 0) { - if (blinker < 255) { - blinker++; - } - else { - blinkerD = 1; - } - } - if (blinkerD == 1) { - if (blinker > 0) { - blinker--; - } - else { - blinkerD = 0; - } - } -} - - -//========================================================================================================= -//========================================================================================================= -// AT42QT2120 Functions -//========================================================================================================= -//========================================================================================================= - -//Check interrupt pin -uint8_t isTouchChangeDetected() -{ - return !digitalRead(0); -} - -//Read data from the cap touch IC -uint8_t readDataFromTS(uint8_t reg) -{ - Wire.beginTransmission(0x1C); - Wire.write(reg); - Wire.endTransmission(); - Wire.requestFrom((uint8_t)0x1C, (uint8_t)1); - if (Wire.available() == 1) - { - return Wire.read(); - } - else { - return 0; - } -} - -//Write data to cap touch IC -uint8_t writeDataToTS(uint8_t reg, uint8_t data) -{ - Wire.beginTransmission(0x1C); - Wire.write(reg); - Wire.write(data); - Wire.endTransmission(); - return 1; -} - - -uint8_t checkTSPres() -{ - uint8_t temp_byte; - temp_byte = readDataFromTS(0x00); - if (temp_byte != 0x3E) - { - return 0; - } - else - { - return 1; - } -} - -//Setup cap touch IC -uint8_t capSetup() -{ - - uint8_t temp_return = checkTSPres(); - - if (temp_return == 1) - { - // Perform measurements every 16ms - writeDataToTS(0x08, 1); - - // Increase detection integrator value - writeDataToTS(0x0B, 1); - - // Oversample to gain two bits for columns - writeDataToTS(0x28, 0x42); - writeDataToTS(0x29, 0x00); - writeDataToTS(0x2A, 0x00); - writeDataToTS(0x2B, 0x00); - writeDataToTS(0x2C, 0x42); - writeDataToTS(0x2D, 0x00); - writeDataToTS(0x2E, 0x00); - writeDataToTS(0x2F, 0x00); - writeDataToTS(0x30, 0x42); - writeDataToTS(0x31, 0x42); - writeDataToTS(0x32, 0x42); - writeDataToTS(0x33, 0x42); - - // Recalibration if touch detected for more than 8 seconds n*0.16s - writeDataToTS(0x0C, 50); - - // Enable keys and set key groups - writeDataToTS(0x1C, 0x00 | 0x04); - writeDataToTS(0x1D, 0x00 | 0x08); - writeDataToTS(0x1E, 0x00 | 0x08); - writeDataToTS(0x1F, 0x00 | 0x08); - writeDataToTS(0x20, 0x00 | 0x04); - writeDataToTS(0x21, 0x00 | 0x08); - writeDataToTS(0x22, 0x00 | 0x08); - writeDataToTS(0x23, 0x00 | 0x08); - writeDataToTS(0x24, 0x00 | 0x04); - writeDataToTS(0x25, 0x00 | 0x04); - writeDataToTS(0x26, 0x00 | 0x04); - writeDataToTS(0x27, 0x00 | 0x04); - - } - return temp_return; -} - -void touchClearCurrentDetections() -{ - uint8_t temp_uint; - temp_uint = readDataFromTS(0x05); - temp_uint = readDataFromTS(0x02); - temp_uint = readDataFromTS(0x03); - temp_uint = readDataFromTS(0x04); -} - -uint16_t touchDetectionRoutine() -{ - uint16_t data; - uint8_t temp1, temp2; - - temp1 = readDataFromTS(0x04); - temp2 = readDataFromTS(0x03); - data = temp1; - data = (data << 8) | temp2; - return data; - -} - +/******************************************************************************* + + MIT License + + Copyright (c) 2018, JacoBurge + + 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. + + ******************************************************************************* + + WARNING: Changing the code in this file could prevent your TouchPad from working! + + *******************************************************************************/ + +//Libraries: +#include +#include +#include + +//Compiler directives: +#define COMPATDELAY 1 //Defines increments in compatibility delay in mS +#define VIBRATE_LENGTH 38 //Defines number of interrupts motor will vibrate for, must be bigger than 8 for correct operation +#define SAFE_MODE //Disables OTG programming after first key press, comment out to disable +//#define RESET //Uncomment to reset EEPROM, upload, and then comment out again to prevent EEPROM being erased on every power cycle + +// KEY definitions - these are the ASCII non-USB based codes as per keyboardUK.h/.cpp +#define KSHIFT KEY_LEFT_SHIFT +#define KUP KEY_UP_ARROW +#define KDOWN KEY_DOWN_ARROW +#define KLEFT KEY_LEFT_ARROW +#define KRIGHT KEY_RIGHT_ARROW +#define KBACK KEY_BACKSPACE +#define KSPACE 0x20 // ASCII 32 SPACE +#define KRETURN KEY_RETURN +#define KLBRACKET 0x5B // ASCII 91 [ +#define KRBRACKET 0x5D // ASCII 93 ] +#define KPIRATE 0x72 // ASCII 114 r The pirates key +#define KPIPE 0x1E // ASCII 30 | PIPE/VBAR +#define KBSLASH 0x1F // ASCII 31 \ BSLASH + +//Function definitions +bool touchDetection(); +void decodeArray(uint16_t dataIn, uint8_t *column, uint8_t *row); +void toggleKey(uint8_t key); +void GUI_keySelected(uint8_t column, uint8_t row); +void GUI_keyClear(); +void GUI_prog(); +void GUI_prog_leds(); +void GUI_menu(); +void GUI_clear_lines(uint8_t line); +void GUI_replace_lines(); +void GUI_replace_functions(uint8_t line); +void GUI_clear(); +void memoryKeyboard(uint16_t address, uint8_t stringLength, uint8_t printl); +void interruptSetup(); +ISR(TIMER1_COMPA_vect); +void pulseLED(); +uint8_t isTouchChangeDetected(); +uint8_t readDataFromTS(uint8_t reg); +uint8_t writeDataToTS(uint8_t reg, uint8_t data); +uint8_t checkTSPres(); +uint8_t capSetup(); +void touchClearCurrentDetections(); +uint16_t touchDetectionRoutine(); +void keyPress(int x, int y, int commandSet); + + +const uint8_t SENr[6] = {1, 2, 3, 5, 6, 7};//Maps capacitive pads to pins +const uint8_t SENc[6] = {0, 4, 8, 9, 10, 11}; + +volatile uint8_t LEDs[6][6];//Stores current LED values +volatile uint8_t col = 0;//Keeps track of current multiplex column for LEDs + +//Stores how to display each key in the 'On the go programmer' in flash +const uint8_t KEYS[100][5] PROGMEM = {" 0 ", " 1 ", " 2 ", " 3 ", " 4 ", " 5 ", " 6 ", " 7 ", " 8 ", " 9 ", + " a ", " b ", " c ", " d ", " e ", " f ", " g ", " h ", " i ", " j ", " k ", " l ", " m ", + " n ", " o ", " p ", " q ", " r ", " s ", " t ", " u ", " v ", " w ", " x ", " y ", " z ", + " F 1 ", " F 2 ", " F 3 ", " F 4 ", " F 5 ", " F 6 ", " F 7 ", " F 8 ", " F 9 ", " F10 ", " F11 ", " F12 ", + "L CTR", "L SHI", "L ALT", "L GUI", "PG UP", "R CTR", "R SHI", "R ALT", "R GUI", "PG DO", "LEFT ", " BSP ", + " ESC ", " HOM ", " UP ", "DOWN ", " TAB ", " INS ", " END ", "RIGHT", " RET ", " DEL ", "CAPS ", "SPACE", + " 1mS ", "10mS ", "100mS", " 1S ", " 5S ", " 10S ", " x2 ", " x3 ", " x4 ", " x5 ", " x10 ", " x20 " + }; + +//Stores ascii values for each keypress in flash +const uint8_t KEYS_PRESS[128] PROGMEM = {48, 49, 50, 51, 52, 53, 54, 55, 56, 57,//9 + 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109,//22 + 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122,//35 + 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205,//47 + 128, 129, 130, 131, 211, 132, 133, 134, 135, 214, 216, 178,//59 + 177, 210, 218, 217, 179, 209, 213, 215, 176, 212, 193, 32,//71(32) + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //83 + 35, 38, 64, 92, 47, 36, 37, 42, 43, 45, 60, 61, 62, 63, 59, 46, 33, //100 + 123, 125, 91, 93, 40, 41, 58, 44, 34, 39, 94, 95, 96, 124, 126, 30, 31 //117 + }; + +//Stores key locations for 'On the go programmer' menu in flash +const uint8_t KEYS_LOCATION[4][6][5] PROGMEM = {{{52, 51 , 50 , 49 , 48}, {57, 56 , 55 , 54 , 53}, {88, 87 , 86 , 85 , 84}, {61, 60 , 59 , 58 , 71}, {66, 65 , 64 , 63 , 62}, {70, 69 , 68 , 67 , 255}}, + {{34, 28 , 22 , 16 , 10}, {35, 29 , 23 , 17 , 11}, {97, 30 , 24 , 18 , 12}, {98, 31 , 25 , 19 , 13}, {99, 32 , 26 , 20 , 14}, {100, 33 , 27 , 21 , 15}}, + {{42, 36 , 91 , 6 , 0}, {43, 37 , 92 , 7 , 1}, {44, 38 , 93 , 8 , 2}, {45, 39 , 94 , 9 , 3}, {46, 40 , 95 , 89 , 4}, {47, 41 , 96 , 90 , 5}}, + {{113, 107 , 101 , 78 , 72}, {114, 108 , 102 , 79 , 73}, {115, 109 , 103 , 80 , 74}, {117 , 110 , 104 , 81 , 75}, {116, 111 , 105 , 82 , 76}, {255, 112 , 106 , 83 , 77}} +}; +//83 + +//Stores 'On the go programmer' strings in flash +const uint8_t STRINGS[43][50] PROGMEM = { + "/ / / * * * / / / /", + "/ L CTR / R CTR / # / SPACE / UP /RELEASE/", + "/ L SHI / R SHI / & / LEFT / DOWN / RIGHT /", + "/ L ALT / R ALT / @ / BSP / TAB / RET /", + "/ L GUI / R GUI / \\ / ESC / INS / DEL /", + "/ PG UP / PG DO / / / HOM / END / CAPS /", + "/ <- - / DEL / FUNCT / abc / F/123 / EXTRA /", + "- - - - - - - - - - - - - - - - - - - - - - - - -",//7 + "/ / / / / / /",//8 + "/ / / / * * * / / /",//9 + "/ a / b / c / d / e / f /", + "/ g / h / i / j / k / l /", + "/ m / n / o / p / q / r /", + "/ s / t / u / v / w / x /", + "/ y / z / ? / ; / . / ! /", + "/ / / / / * * * / /", + "/ 0 / 1 / 2 / 3 / 4 / 5 /", + "/ 6 / 7 / 8 / 9 / $ / % /", + "/ F 1 / F 2 / F 3 / F 4 / F 5 / F 6 /", + "/ F 7 / F 8 / F 9 / F10 / F11 / F12 /",//19 + "/ / / / / / * * * /", + "!!! Warning !!! When in the programming modes, ",//21 + "TouchPad takes control of your keyboard, this co ", + "uld EDIT or DELETE text or files if you leave thi", + "s window. !!! Warning !!! ",//24 + "Now in macro program mode, for command set ",//25 + "Use the following menus to assign keys on the key",//26 + "pad to macro keys for your program ",//27 + "Now in LED program mode, for command set ",//28 + "Touch LEDs to toggle them and swipe down when com",//29 + "plete ",//30 + "Programming complete, you can now close the notep", + "ad and safely resume work... ", + "No key selected. ",//33 + "Key ", + ", ", + " selected: ", + "/ 1mS / 10mS / 100mS / 1S / 5S / 10S /",//37 + "/ x2 / x3 / x4 / x5 / x10 / x20 /", + "/ * / + / - / < / = / > /",//39 + "/ { / } / [ / ] / ( / ) /", + "/ : / , / \" / ' / ^ / _ /", + "/ ` / | / ~ / "//42 +}; + +volatile enum GUI {NORMAL, PROG, PROG1, PROG_LEDS, PROG_LEDS1, CHANGE_MODE, NORMAL1, FACTORY} state;//State machine variable for UI +volatile uint32_t blinkerC = 0; //Timing for blinking LED +volatile uint8_t blinker = 0, blinkerD = 0; //Counter and direction for blinking LED +volatile uint8_t vibrate = 0; //Trigger vibration in interrupt +uint8_t progR = 10, progC = 10;//10 when no key selected, row and column when key selected +uint8_t GUI_Menu = 0;//Stores current GUI menu, 0 when none displayed, 1-4 for menus, 5 for clear + +int8_t currentMode = 0;//Stores current mode 0 - 4 +uint16_t compat = 0;//Compatibility mode off; +uint8_t setupEnable = 1;//No entering prog mode after first key press +uint8_t factoryTest[12];//Used for factory testing of keys + +//========================================================================================================= +//========================================================================================================= +// Setup +//========================================================================================================= +//========================================================================================================= + +void setup() { + Serial.begin(9600); + Wire.begin(); + Keyboard.begin(); + Mouse.begin(); + + pinMode(7, OUTPUT);//Motor enable + pinMode(6, OUTPUT);//Motor PWM + + pinMode(11, OUTPUT);//Power LED + + pinMode(A0, OUTPUT);//LEDs Columns + pinMode(A1, OUTPUT); + pinMode(A2, OUTPUT); + pinMode(A3, OUTPUT); + pinMode(A4, OUTPUT); + pinMode(A5, OUTPUT); + + pinMode(12, OUTPUT);//LEDs Rows + pinMode(8, OUTPUT); + pinMode(9, OUTPUT); + pinMode(10, OUTPUT); + pinMode(5, OUTPUT); + pinMode(13, OUTPUT); + + pinMode(0, INPUT);//Capacitive Interrupt + + if (EEPROM.read(1023) != 20) {//Setup EEPROM when first power up + digitalWrite(11, 1); + for (uint8_t j = 0; j < 5; j++) {//Setup EEPROM for default TouchPad + for (uint8_t i = 0; i < 180; i++) { + EEPROM.write((j * 200) + i, 255); + } + } + for (uint8_t j = 0; j < 5; j++) { + uint8_t i = 0; + for ( i = 180; i < 181 + j; i++) { + EEPROM.write((j * 200) + i, 1); + } + for ( i; i < 186; i++) { + EEPROM.write((j * 200) + i, 0); + } + } + EEPROM.write(1023, 20);//Setup complete + EEPROM.write(1022, 0);//Current Mode + EEPROM.write(1021, 20);//Factory Pass not complete + EEPROM.write(1020, 0); //Compat setting + + state = FACTORY; + for (int i = 0; i < 12; i++) {//All ones must be cleared to pass. set them here + factoryTest[i] = 1; + } + } + +#ifdef RESET + EEPROM.write(1023, 0);//Perform eeprom reset, setup will be performed on next power cycle +#endif + + if (EEPROM.read(1021) == 20) {//If factory test not complete, put it in this mode + state = FACTORY; + for (int i = 0; i < 12; i++) { + factoryTest[i] = 1; + } + } + +#ifdef ENABLE_MULTIPLE_COMMAND_SET + currentMode = EEPROM.read(1022);//Load current mode from EEPROM +#else + currentMode = 0; +#endif + + compat = EEPROM.read(1020);//Load compat setting from EEPROM + + if (currentMode > 4) {//Limit current mode to 0-5 + currentMode = 4; + } + else if (currentMode < 0) { + currentMode = 0; + } + + for (uint8_t i = 0; i < 6; i++) {//Clear all LEDs + for (uint8_t j = 0; j < 6; j++) { + LEDs[j][i] = 0; + } + } + + interruptSetup();//Setup LED matrix driver interrupt + + if (state != FACTORY) {//If not still in factory test + delay(2000); + digitalWrite(11, HIGH);//Light power LED briefly, signals calibrating + delay(100); + digitalWrite(11, LOW); + } + + capSetup();//Setup capacitive touch IC + writeDataToTS(0x06, 0x12);//Calibrate capacitive touch IC + + if (state != FACTORY) {//Set LEDs to match the current command set + delay(1000); + for (uint8_t i = 0; i < 6; i++) { + for (uint8_t j = 0; j < 6; j++) { + LEDs[j][i] = bitRead(EEPROM.read((currentMode * 200) + 180 + (j)), i);//Load values from EEPROM + } + } + } +} + +//========================================================================================================= +//========================================================================================================= +// Loop +//========================================================================================================= +//========================================================================================================= + +void loop() { + + switch (state) { //Main state machine for operation + case NORMAL: + touchDetection(); //Run touchDetection + analogWrite(11, blinker); //Update LED + if (blinker < 255) { + if (millis() > blinkerC) { + analogWrite(11, blinker); + blinker++; + blinkerC = millis() + 1; + } + } + break; + case PROG: + touchDetection(); //Run touchDetection + if (millis() > blinkerC) { //Update LED + analogWrite(11, blinker); + pulseLED(); + blinkerC = millis() + 4; + } + break; + case PROG_LEDS: + touchDetection(); //Run touchDetection + if (millis() > blinkerC) { //Update LED + analogWrite(11, blinker); + pulseLED(); + blinkerC = millis() + 1; + } + break; + case FACTORY: //Only occurs when EEPROM reset. + //Wait for all inputs to be tested + if (factoryTest[0] + factoryTest[1] + factoryTest[2] + factoryTest[3] + factoryTest[4] + factoryTest[5] + factoryTest[6] + factoryTest[7] + factoryTest[8] + factoryTest[9] + factoryTest[10] + factoryTest[11] > 0) { + touchDetection(); //Run touchDetection + if (millis() > blinkerC) { + digitalWrite(11, !digitalRead(11)); + blinkerC = millis() + 300; + } + } + else { //Test all LEDs + for (uint8_t i = 0; i < 6; i++) { + for (uint8_t j = 0; j < 6; j++) { + LEDs[j][i] = 0; + } + } + for (uint8_t i = 0; i < 6; i++) { + for (uint8_t j = 0; j < 6; j++) { + LEDs[j][i] = 1; + } + delay(200); + for (uint8_t j = 0; j < 6; j++) { + LEDs[j][i] = 0; + } + } + for (uint8_t i = 0; i < 6; i++) { + for (uint8_t j = 0; j < 6; j++) { + LEDs[i][j] = 1; + } + delay(200); + for (uint8_t j = 0; j < 6; j++) { + LEDs[i][j] = 0; + } + } + for (uint8_t i = 0; i < 6; i++) { //Load current LED pattern + for (uint8_t j = 0; j < 6; j++) { + LEDs[j][i] = bitRead(EEPROM.read((currentMode * 200) + 180 + (j)), i); + } + } + state = NORMAL; //Enter normal operation + EEPROM.write(1021, 0); //Set factory test pass + } + break; + } +} + +//========================================================================================================= +//========================================================================================================= +// Check capacitive array - Returns 1 for positive ID, 0 for negative ID +//========================================================================================================= +//========================================================================================================= + +bool touchDetection() { + if (isTouchChangeDetected()) { + uint16_t dataIn, row = 10, column = 10; + dataIn = touchDetectionRoutine(); + if ((dataIn & 0b111100010001) > 0 && (dataIn & 0b000011101110) > 0) { + uint8_t column, row; + decodeArray(dataIn, &column, &row); + + if (column != 10 && row != 10) { + vibrate = VIBRATE_LENGTH; //Trigger vibration + + LEDs[column][row] = 1; + dataIn = touchDetectionRoutine(); + while ((dataIn & (0b1 << SENr[row])) > 0 || (dataIn & (0b1 << SENc[column])) > 0) { + dataIn = touchDetectionRoutine(); +#ifdef ENABLE_MULTIPLE_COMMAND_SET //disable multiple command sets + //Horizontal swipe detect + if ((dataIn & (0b1 << SENr[row])) > 0 && (dataIn & (0b1 << SENc[column])) == 0 && (dataIn & 0b111100010001) > 0 && state == NORMAL) { + uint8_t columnNew, rowNew; + decodeArray(dataIn, &columnNew, &rowNew); + + if (columnNew > column) { + //===============================================================================================Swipe Right... + for (uint8_t i = column; i < 6; i++) { + LEDs[i][row] = 1; + delay(50); + } + currentMode--; + if (currentMode < 0) { + currentMode = 4; + } + EEPROM.write(1022, currentMode); + //Keyboard.println(currentMode); + + digitalWrite(7, HIGH); + analogWrite(6, 180); + for (int8_t i = 6; i >= 0; i--) { //Change + if (i < 4) { + analogWrite(6, 127); + digitalWrite(7, LOW); + } + for (uint8_t j = 0; j < 6; j++) { + for (uint8_t k = 0; k < 6; k++) { + LEDs[j][k] = 0; + if (j - i >= 0) { + LEDs[j - i][k] = bitRead(EEPROM.read((currentMode * 200) + 180 + (j)), k); + } + } + } + delay(100); + } + + state = CHANGE_MODE; + + //===============================================================================================...Swipe Right + } + else { + //===============================================================================================Swipe Left... + for (int8_t i = column; i >= 0; i--) { + LEDs[i][row] = 1; + delay(50); + } + + currentMode++; + if (currentMode > 4) { + currentMode = 0; + } + EEPROM.write(1022, currentMode); + //Keyboard.println(currentMode); + + digitalWrite(7, HIGH); + analogWrite(6, 180); + for (int8_t i = 6; i >= 0; i--) { //Change + if (i < 4) { + analogWrite(6, 127); + digitalWrite(7, LOW); + } + for (uint8_t j = 0; j < 6; j++) { + for (uint8_t k = 0; k < 6; k++) { + LEDs[j][k] = 0; + } + } + for (uint8_t j = 0; j < 6; j++) { + for (uint8_t k = 0; k < 6; k++) { + if (j + i <= 5 ) { + LEDs[j + i][k] = bitRead(EEPROM.read((currentMode * 200) + 180 + (j)), k); + } + } + } + delay(100); + } + state = CHANGE_MODE; + + //===============================================================================================...Swipe Left + } + + while ((dataIn & (0b1 << SENr[row])) > 0 || (dataIn & (0b1 << SENc[column])) > 0) { + dataIn = touchDetectionRoutine(); + } + break; + } +#endif +#ifdef ENABLE_OTG_PROGRAMMER + //Vertical swipe detect + if ((dataIn & (0b1 << SENc[column])) > 0 && (dataIn & (0b1 << SENr[row])) == 0 && (dataIn & 0b000011101110) > 0) { + uint8_t columnNew, rowNew; + decodeArray(dataIn, &columnNew, &rowNew); + if (rowNew > row) { + //===============================================================================================Swipe Up... + + if (state == NORMAL) { + if (setupEnable == 1) { //Only enter setup mode immediately after power up! + for (uint8_t i = row; i < 6; i++) { + LEDs[column][i] = 1; + delay(50); + } + + digitalWrite(7, HIGH); + analogWrite(6, 180); + for (int8_t i = 6; i >= 0; i--) { + for (uint8_t j = 0; j < 6; j++) { + for (uint8_t k = 0; k < 6; k++) { + LEDs[j][k] = 0; + if (k - i >= 0) { + LEDs[j][k - i] = bitRead(EEPROM.read((currentMode * 200) + 180 + (j)), k); + } + } + } + delay(100); + } + analogWrite(6, 127); + digitalWrite(7, LOW); + state = PROG_LEDS1; + } + } + else if (state == PROG) { + digitalWrite(7, HIGH); + analogWrite(6, 180); + for (uint8_t i = row; i < 6; i++) { + LEDs[column][i] = 1; + delay(100); + } + analogWrite(6, 127); + digitalWrite(7, LOW); + state = NORMAL1; + GUI_clear(); + } + + //===============================================================================================...Swipe Up + } + else { + //===============================================================================================Swipe Down... + if (state == NORMAL) { + if (setupEnable == 1) { //Only enter setup mode immediately after power up! + digitalWrite(7, HIGH); + analogWrite(6, 180); + for (int8_t i = row; i >= 0; i--) { + LEDs[column][i] = 1; + delay(100); + } + analogWrite(6, 127); + digitalWrite(7, LOW); + state = PROG1; + + } + } + else if (state == PROG) { + digitalWrite(7, HIGH); + analogWrite(6, 180); + for (int8_t i = row; i >= 0; i--) { + LEDs[column][i] = 1; + delay(100); + } + analogWrite(6, 127); + digitalWrite(7, LOW); + Keyboard.releaseAll(); + compat += COMPATDELAY; + EEPROM.write(1020, compat); + GUI_clear(); + Keyboard.press(KSHIFT); + for (uint8_t i = 0; i < 3; i++) { + toggleKey(KUP); + } + Keyboard.release(KSHIFT); + toggleKey(KBACK); + state = PROG1; + } + + else if (state == PROG_LEDS) { + + for (int8_t i = row; i >= 0; i--) { + LEDs[column][i] = 1; + delay(50); + } + digitalWrite(7, HIGH); + analogWrite(6, 180); + for (uint8_t i = 0; i <= 6; i++) { + + + + for (uint8_t j = 0; j < 6; j++) { + for (uint8_t k = 0; k < 6; k++) { + LEDs[j][k] = 0; + if (k - i >= 0) { + LEDs[j][k - i] = bitRead(EEPROM.read((currentMode * 200) + 180 + (j)), k); + } + } + } + delay(100); + } + analogWrite(6, 127); + digitalWrite(7, LOW); + state = NORMAL1; + GUI_clear(); + } + //===============================================================================================...Swipe Down + + } + + while ((dataIn & (0b1 << SENr[row])) > 0 || (dataIn & (0b1 << SENc[column])) > 0) { + dataIn = touchDetectionRoutine(); + } + break; + } +#endif + //===============================================================================================While Pressed... + + + //===============================================================================================...While Pressed + } + touchClearCurrentDetections(); + + //===============================================================================================When Released... + uint8_t repeat[5] = {0, 0, 0, 0, 0}; + switch (state) { + case CHANGE_MODE: + state = NORMAL; + break; + case FACTORY: + factoryTest[row] = 0; + factoryTest[6 + column] = 0; + break; + case NORMAL: + if (setupEnable == 1) { +#ifdef SAFE_MODE + setupEnable = 0; +#endif + } + for (uint8_t i = 0; i < 6; i++) { + for (uint8_t j = 0; j < 6; j++) { + LEDs[i][j] = 0; + } + } + + for (int i = 0; i < 5; i++) { +#ifdef ENABLE_OTG_PROGRAMMER + uint8_t temp = EEPROM.read((currentMode * 200) + (column * 30) + (row * 5) + i); + if (temp != 255) { + if (((temp & 0b01111111) < 72) || ((temp & 0b01111111) > 83)) { + uint8_t key = pgm_read_byte(&(KEYS_PRESS[temp & 0b01111111])); + Keyboard.press(key); + if (temp > 127) { + Keyboard.releaseAll(); + } + } + else if (((temp & 0b01111111) >= 72 ) && ((temp & 0b01111111) <= 77)) { + switch (temp & 0b01111111) { + case 72: delay(1); break; + case 73: delay(10); break; + case 74: delay(100); break; + case 75: delay(1000); break; + case 76: delay(5000); break; + case 77: delay(10000); break; + } + } + else { + if (repeat[i] > 0) { + repeat[i]--; + if (repeat[i] > 0) { + i = -1; + } + } + else { + switch (temp & 0b01111111) { + case 78: repeat[i] = 1; break; + case 79: repeat[i] = 2; break; + case 80: repeat[i] = 3; break; + case 81: repeat[i] = 4; break; + case 82: repeat[i] = 9; break; + case 83: repeat[i] = 19; break; + + } + i = -1; + } + } + } + else { +#endif + if (i == 0) { + keyPress(column, row, currentMode + 1); //If key not programmed, default to info stored in flash (KeyDefinitions.h ?) + } + break; +#ifdef ENABLE_OTG_PROGRAMMER + } +#endif + } +#ifdef ENABLE_DEFAULT_RELEASE + Keyboard.releaseAll(); +#endif + + break; + case NORMAL1: + for (uint8_t i = 0; i < 6; i++) { + for (uint8_t j = 0; j < 6; j++) { + LEDs[i][j] = 0; + } + } + state = NORMAL; + break; + case PROG1: + for (uint8_t i = 0; i < 6; i++) { + for (uint8_t j = 0; j < 6; j++) { + LEDs[i][j] = 0; + } + } + if (compat > 0) { + Keyboard.print("Compatibility level: "); + Keyboard.print(compat / COMPATDELAY); + Keyboard.releaseAll(); + } + GUI_prog(); + state = PROG; + progR = 10; + progC = 10; + GUI_Menu = 0; + GUI_keySelected(progC, progR); + GUI_menu(); + GUI_Menu = 6; + break; + case PROG: + for (uint8_t i = 0; i < 6; i++) { + for (uint8_t j = 0; j < 6; j++) { + LEDs[i][j] = 0; + } + } + + if (progC != 10 || progR != 10) { + LEDs[progC][progR] = 1; + } + + if (progC == 10 || progR == 10) { + progC = column; + progR = row; + LEDs[progC][progR] = 1; + GUI_keyClear(); + GUI_menu(); + GUI_Menu = 1; + } + else if (column == 0 && row == 5) { + LEDs[progC][progR] = 0; + progC = 10; + progR = 10; + GUI_keyClear(); + GUI_Menu = 5; + GUI_menu(); + } + else if (column == 1 && row == 5 ) { + for (uint8_t i = 0; i < 4; i++) { + if (EEPROM.read((currentMode * 200) + (progC * 30) + (progR * 5) + (i + 1)) == 255) { + EEPROM.write((currentMode * 200) + (progC * 30) + (progR * 5) + (i), 255); + } + } + if (EEPROM.read((currentMode * 200) + (progC * 30) + (progR * 5) + (4)) != 255) { + EEPROM.write((currentMode * 200) + (progC * 30) + (progR * 5) + (4), 255); + } + GUI_keyClear(); + } + else if (column == 2 && row == 5 && GUI_Menu != 1) { + GUI_Menu = 1; + GUI_menu(); + } + else if (column == 3 && row == 5 && GUI_Menu != 2) { + GUI_Menu = 2; + GUI_menu(); + } + else if (column == 4 && row == 5 && GUI_Menu != 3) { + GUI_Menu = 3; + GUI_menu(); + } + else if (column == 5 && row == 5 && GUI_Menu != 4) { + GUI_Menu = 4; + GUI_menu(); + } + else if (column == 5 && row == 0 && GUI_Menu == 4) { + compat = 0; + EEPROM.write(1020, compat); + } + else if (column == 5 && row == 4 && GUI_Menu == 1 ) {//Release + for (uint8_t i = 1; i < 6; i++) { + if (EEPROM.read((currentMode * 200) + (progC * 30) + (progR * 5) + (i)) == 255 || i == 5) { + uint8_t temp = EEPROM.read((currentMode * 200) + (progC * 30) + (progR * 5) + (i - 1)); + if (temp != 255) { + if (((temp & 0b01111111) < 72) || ((temp & 0b01111111) > 83) ) { + if (temp > 127) { + EEPROM.write((currentMode * 200) + (progC * 30) + (progR * 5) + (i - 1), temp & 127); + } + else { + EEPROM.write((currentMode * 200) + (progC * 30) + (progR * 5) + (i - 1), temp | 128); + } + } + GUI_keyClear(); + } + break; + } + } + + } + else if (row < 5 && pgm_read_byte(&(KEYS_LOCATION[GUI_Menu - 1][column][row])) != 255 && GUI_Menu > 0 && GUI_Menu < 5) { + for (uint8_t i = 0; i < 5; i++) { + if (EEPROM.read((currentMode * 200) + (progC * 30) + (progR * 5) + (i)) == 255) { + EEPROM.write((currentMode * 200) + (progC * 30) + (progR * 5) + (i), pgm_read_byte(&(KEYS_LOCATION[GUI_Menu - 1][column][row]))); + break; + } + } + GUI_keyClear(); + } + break; + case PROG_LEDS1: + for (uint8_t i = 0; i < 6; i++) { + for (uint8_t j = 0; j < 6; j++) { + LEDs[i][j] = bitRead(EEPROM.read((currentMode * 200) + 180 + (i)), j); + } + } + GUI_prog_leds(); + state = PROG_LEDS; + break; + case PROG_LEDS: + if (row > 0) { + uint8_t temp = EEPROM.read((currentMode * 200) + 180 + (column)); + bitWrite(temp, row, !bitRead(temp, row)); + EEPROM.write((currentMode * 200) + 180 + (column), temp); + } + for (uint8_t i = 0; i < 6; i++) { + for (uint8_t j = 0; j < 6; j++) { + LEDs[i][j] = bitRead(EEPROM.read((currentMode * 200) + 180 + (i)), j); + } + } + break; + + } + //===============================================================================================...When Released + return 1; + } + } + else { + touchClearCurrentDetections(); + } + } + return 0; +} + +//Process raw capacitive data, map pins to rows and columns +void decodeArray(uint16_t dataIn, uint8_t *column, uint8_t *row) { + uint8_t i1 = 20, i2 = 20; + for (uint8_t i = 0; i < 12; i++) { + if ((dataIn & 0b1) == 1) { + if (i1 == 20) { + i1 = i; + } + else if (i2 == 20) { + i2 = i; + } + } + dataIn = dataIn >> 1; + } + + for (uint8_t j = 0; j < 6; j++) { + if (SENr[j] == i1 || SENr[j] == i2) { + *row = j; + } + if (SENc[j] == i1 || SENc[j] == i2) { + *column = j; + } + } +} + +//========================================================================================================= +//========================================================================================================= +// GUI Functions +//========================================================================================================= +//========================================================================================================= + +//Press key on keyboard, perform compat delay +void toggleKey(uint8_t key) { + Keyboard.press(key); + Keyboard.release(key); + if (compat > 0) { + delay(compat); + } +} + +//Update current key selection list +void GUI_keySelected(uint8_t column, uint8_t row) { + if (column == 10 || row == 10) { + memoryKeyboard(33, 49, 0); + } + else { + memoryKeyboard(34, 4, 0); + Keyboard.print(column); + memoryKeyboard(35, 1, 0); + Keyboard.print(row); + memoryKeyboard(36, 11, 0); + for (uint8_t i = 0; i < 5; i++) { + uint8_t temp1 = EEPROM.read((currentMode * 200) + (column * 30) + (row * 5) + (i)); + if (temp1 != 255) { + toggleKey(KLBRACKET); + if ((temp1 & 0b01111111) < 84) { + for (uint8_t j = 0; j < 5; j++) { + toggleKey(pgm_read_byte(&(KEYS[temp1 & 0b01111111][j]))); + } + } + else { + toggleKey(KSPACE); + toggleKey(KSPACE); + toggleKey(pgm_read_byte(&(KEYS_PRESS[temp1 & 0b01111111]))); + toggleKey(KSPACE); + toggleKey(KSPACE); + } + toggleKey(KRBRACKET); + if (temp1 > 127) { // Modifier or non ASCII key + toggleKey(KPIRATE); // r The pirates key + } + else { + toggleKey(KSPACE); + } + } + else { + for (uint8_t j = 0; j < (8 * (5 - i)); j++) { + toggleKey(KSPACE); + } + break; + } + } + } + toggleKey(KRETURN); + toggleKey(KRETURN); + Keyboard.releaseAll(); +} + +//Clear current key selection +void GUI_keyClear() { + for (uint8_t i = 0; i < 26; i++) { + toggleKey(KUP); + } + toggleKey(KDOWN); + toggleKey(KLEFT); + + Keyboard.press(KSHIFT); + Keyboard.press(KUP); + Keyboard.releaseAll(); + toggleKey(KBACK); + toggleKey(KRETURN); + GUI_keySelected(progC, progR); + toggleKey(KBACK); + toggleKey(KBACK); + for (uint8_t i = 0; i < 26; i++) { + toggleKey(KDOWN); + } + toggleKey(KLEFT); + toggleKey(KDOWN); + Keyboard.releaseAll(); +} + +//Type basic prog interface +void GUI_prog() { + toggleKey(KRETURN); + toggleKey(KRETURN); + memoryKeyboard(21, 49, 0); + memoryKeyboard(22, 48, 0); + memoryKeyboard(23, 49, 0); + memoryKeyboard(24, 27, 0); + toggleKey(KRETURN); + toggleKey(KRETURN); + memoryKeyboard(25, 43, 0); + Keyboard.print((currentMode + 1)); + toggleKey(KRETURN); + toggleKey(KRETURN); + memoryKeyboard(26, 49, 0); + memoryKeyboard(27, 34, 0); + toggleKey(KRETURN); + toggleKey(KRETURN); + Keyboard.releaseAll(); +} + +//Type basic LED prog interface +void GUI_prog_leds() { + toggleKey(KRETURN); + toggleKey(KRETURN); + memoryKeyboard(21, 49, 0); + memoryKeyboard(22, 48, 0); + memoryKeyboard(23, 49, 0); + memoryKeyboard(24, 27, 0); + toggleKey(KRETURN); + toggleKey(KRETURN); + memoryKeyboard(28, 41, 0); + Keyboard.print((currentMode + 1 )); + toggleKey(KRETURN); + toggleKey(KRETURN); + memoryKeyboard(29, 49, 0); + memoryKeyboard(30, 5, 0); + Keyboard.releaseAll(); +} + +//Manage typing and clearing GUI menus for prog interface +void GUI_menu() { + toggleKey(KRIGHT); + switch (GUI_Menu) { + case 0: + for (uint8_t i = 0; i < 6; i++) { + memoryKeyboard(7, 49, 1); + memoryKeyboard(8, 49, 1); + memoryKeyboard(8, 49, 1); + memoryKeyboard(8, 49, 1); + } + memoryKeyboard(7, 49, 0); + GUI_Menu = 1; + break; + case 1: + for (uint8_t i = 0; i < 21; i++) { + toggleKey(KUP); + } + GUI_replace_lines(); + memoryKeyboard(0, 49, 0); + GUI_replace_functions(3); + memoryKeyboard(1, 49, 0); + GUI_replace_functions(4); + memoryKeyboard(2, 49, 0); + GUI_replace_functions(4); + memoryKeyboard(3, 49, 0); + GUI_replace_functions(4); + memoryKeyboard(4, 49, 0); + GUI_replace_functions(4); + memoryKeyboard(5, 49, 0); + toggleKey(KDOWN); + toggleKey(KDOWN); + break; + case 2: + for (uint8_t i = 0; i < 21; i++) { + toggleKey(KUP); + } + GUI_replace_lines(); + memoryKeyboard(9, 49, 0); + GUI_replace_functions(3); + memoryKeyboard(10, 49, 0); + GUI_replace_functions(4); + memoryKeyboard(11, 49, 0); + GUI_replace_functions(4); + memoryKeyboard(12, 49, 0); + GUI_replace_functions(4); + memoryKeyboard(13, 49, 0); + GUI_replace_functions(4); + memoryKeyboard(14, 49, 0); + toggleKey(KDOWN); + toggleKey(KDOWN); + break; + case 3: + for (uint8_t i = 0; i < 21; i++) { + toggleKey(KUP); + } + GUI_replace_lines(); + memoryKeyboard(15, 49, 0); + GUI_replace_functions(3); + memoryKeyboard(16, 49, 0); + GUI_replace_functions(4); + memoryKeyboard(17, 49, 0); + GUI_replace_functions(4); + memoryKeyboard(39, 49, 0); + GUI_replace_functions(4); + memoryKeyboard(18, 49, 0); + GUI_replace_functions(4); + memoryKeyboard(19, 49, 0); + toggleKey(KDOWN); + toggleKey(KDOWN); + break; + case 4: + for (uint8_t i = 0; i < 21; i++) { + toggleKey(KUP); + } + GUI_replace_lines(); + memoryKeyboard(20, 49, 0); + GUI_replace_functions(3); + memoryKeyboard(37, 49, 0); + GUI_replace_functions(4); + memoryKeyboard(38, 49, 0); + GUI_replace_functions(4); + memoryKeyboard(40, 49, 0); + GUI_replace_functions(4); + memoryKeyboard(41, 49, 0); + GUI_replace_functions(4); + memoryKeyboard(42, 28, 0); + toggleKey(KBSLASH); + Keyboard.print(" / "); + toggleKey(KPIPE); + Keyboard.print(" / R C /"); + toggleKey(KDOWN); + toggleKey(KDOWN); + break; + case 5: + + for (uint8_t i = 0; i < 22; i++) { + toggleKey(KUP); + } + GUI_replace_lines(); + memoryKeyboard(8, 49, 0); + GUI_replace_functions(1); + memoryKeyboard(8, 49, 0); + GUI_replace_functions(3); + memoryKeyboard(8, 49, 0); + GUI_replace_functions(4); + memoryKeyboard(8, 49, 0); + GUI_replace_functions(4); + memoryKeyboard(8, 49, 0); + GUI_replace_functions(4); + memoryKeyboard(8, 49, 0); + GUI_replace_functions(4); + memoryKeyboard(8, 49, 0); + toggleKey(KDOWN); + toggleKey(KDOWN); + GUI_Menu = 6; + break; + case 6: + for (uint8_t i = 0; i < 22; i++) { + toggleKey(KUP); + } + GUI_replace_lines(); + memoryKeyboard(6, 49, 0); + GUI_replace_functions(1); + memoryKeyboard(0, 49, 0); + GUI_replace_functions(3); + memoryKeyboard(1, 49, 0); + GUI_replace_functions(4); + memoryKeyboard(2, 49, 0); + GUI_replace_functions(4); + memoryKeyboard(3, 49, 0); + GUI_replace_functions(4); + memoryKeyboard(4, 49, 0); + GUI_replace_functions(4); + memoryKeyboard(5, 49, 0); + toggleKey(KDOWN); + toggleKey(KDOWN); + break; + } + Keyboard.releaseAll(); +} + +//Clear x number lines above cursor position +void GUI_clear_lines(uint8_t line) { + Keyboard.press(KSHIFT); + for (uint8_t i = 0; i < line; i++) { + toggleKey(KUP); + } + Keyboard.release(KSHIFT); + toggleKey(KBACK); +} + +//Delete single line left of cursor +void GUI_replace_lines() { + Keyboard.press(KSHIFT); + toggleKey(KUP); + Keyboard.release(KSHIFT); + toggleKey(KRETURN); +} + +//Scroll down and call replace line +void GUI_replace_functions(uint8_t line) { + for (uint8_t i = 0; i < line; i++) { + toggleKey(KDOWN); + } + GUI_replace_lines(); +} + +//Delete all and type prog done message +void GUI_clear() { + Keyboard.press(KSHIFT); + for (uint8_t i = 0; i < 35; i++) { + toggleKey(KUP); + } + Keyboard.release(KSHIFT); + toggleKey(KBACK); + toggleKey(KRETURN); + Keyboard.releaseAll(); + memoryKeyboard(31, 49, 0); + memoryKeyboard(32, 28, 0); + //Keyboard.println(""); + Keyboard.releaseAll(); +} + +//Type data from program memory +void memoryKeyboard(uint16_t address, uint8_t stringLength, uint8_t printl) { + + for (uint8_t j = 0; j < stringLength; j++) { + toggleKey(pgm_read_byte(&(STRINGS[address][j]))); + } + if (printl == 1) { + toggleKey(KRETURN); + } +} + +//========================================================================================================= +//========================================================================================================= +// LED Display Functions +//========================================================================================================= +//========================================================================================================= + +//Setup interrupt to handle LEDs +void interruptSetup() { + cli(); // disable global interrupts + TCCR1A = 0; // set entire TCCR1A register to 0 + TCCR1B = 0; // same for TCCR1B + // set compare match register to desired timer count + OCR1A = 10; + // turn on CTC mode: + TCCR1B |= (1 << WGM12); + // Set CS10 and CS12 bits for 1024 prescaler + TCCR1B |= (1 << CS10); + TCCR1B |= (1 << CS12); + // enable timer compare interrupt + TIMSK1 |= (1 << OCIE1A); + // enable global interrupts + TCNT1 = 0; + sei(); +} + +//LED driving interrupt +ISR(TIMER1_COMPA_vect) { + + for (uint8_t c = 0; c < 6; c ++) { + switch (c) { + case 0: digitalWrite(12, 0); break; + case 1: digitalWrite(8, 0); break; + case 2: digitalWrite(9, 0); break; + case 3: digitalWrite(10, 0); break; + case 4: digitalWrite(5, 0); break; + case 5: digitalWrite(13, 0); break; + } + } + + switch (col) { + case 0: digitalWrite(A0, 1); break; + case 1: digitalWrite(A2, 1); break; + case 2: digitalWrite(A3, 1); break; + case 3: digitalWrite(A4, 1); break; + case 4: digitalWrite(A5, 1); break; + case 5: digitalWrite(A1, 1); break; + } + + switch (col) { + case 0: digitalWrite(A2, 0); break; + case 1: digitalWrite(A3, 0); break; + case 2: digitalWrite(A4, 0); break; + case 3: digitalWrite(A5, 0); break; + case 4: digitalWrite(A1, 0); break; + case 5: digitalWrite(A0, 0); break; + } + + for (uint8_t c = 0; c < 6; c ++) { + switch (c) { + case 0: digitalWrite(12, LEDs[col][c]); break; + case 1: digitalWrite(8, LEDs[col][c]); break; + case 2: digitalWrite(9, LEDs[col][c]); break; + case 3: digitalWrite(10, LEDs[col][c]); break; + case 4: digitalWrite(5, LEDs[col][c]); break; + case 5: digitalWrite(13, LEDs[col][c]); break; + } + } + + col++; + if (col > 5) { + col = 0; + } + + if (vibrate == VIBRATE_LENGTH) { + digitalWrite(7, HIGH); + analogWrite(6, 255); + vibrate--; + } + else if (vibrate == 8) { + analogWrite(6, 0); + vibrate--; + } + else if (vibrate == 1) { + analogWrite(6, 127); + digitalWrite(7, LOW); + vibrate--; + } + else if (vibrate > 0) { + vibrate--; + } +} + +//Handle power LED fades +void pulseLED() { + if (blinkerD == 0) { + if (blinker < 255) { + blinker++; + } + else { + blinkerD = 1; + } + } + if (blinkerD == 1) { + if (blinker > 0) { + blinker--; + } + else { + blinkerD = 0; + } + } +} + + +//========================================================================================================= +//========================================================================================================= +// AT42QT2120 Functions +//========================================================================================================= +//========================================================================================================= + +//Check interrupt pin +uint8_t isTouchChangeDetected() +{ + return !digitalRead(0); +} + +//Read data from the cap touch IC +uint8_t readDataFromTS(uint8_t reg) +{ + Wire.beginTransmission(0x1C); + Wire.write(reg); + Wire.endTransmission(); + Wire.requestFrom((uint8_t)0x1C, (uint8_t)1); + if (Wire.available() == 1) + { + return Wire.read(); + } + else { + return 0; + } +} + +//Write data to cap touch IC +uint8_t writeDataToTS(uint8_t reg, uint8_t data) +{ + Wire.beginTransmission(0x1C); + Wire.write(reg); + Wire.write(data); + Wire.endTransmission(); + return 1; +} + + +uint8_t checkTSPres() +{ + uint8_t temp_byte; + temp_byte = readDataFromTS(0x00); + if (temp_byte != 0x3E) + { + return 0; + } + else + { + return 1; + } +} + +//Setup cap touch IC +uint8_t capSetup() +{ + + uint8_t temp_return = checkTSPres(); + + if (temp_return == 1) + { + // Perform measurements every 16ms + writeDataToTS(0x08, 1); + + // Increase detection integrator value + writeDataToTS(0x0B, 1); + + // Oversample to gain two bits for columns + writeDataToTS(0x28, 0x42); + writeDataToTS(0x29, 0x00); + writeDataToTS(0x2A, 0x00); + writeDataToTS(0x2B, 0x00); + writeDataToTS(0x2C, 0x42); + writeDataToTS(0x2D, 0x00); + writeDataToTS(0x2E, 0x00); + writeDataToTS(0x2F, 0x00); + writeDataToTS(0x30, 0x42); + writeDataToTS(0x31, 0x42); + writeDataToTS(0x32, 0x42); + writeDataToTS(0x33, 0x42); + + // Recalibration if touch detected for more than 8 seconds n*0.16s + writeDataToTS(0x0C, 50); + + // Enable keys and set key groups + writeDataToTS(0x1C, 0x00 | 0x04); + writeDataToTS(0x1D, 0x00 | 0x08); + writeDataToTS(0x1E, 0x00 | 0x08); + writeDataToTS(0x1F, 0x00 | 0x08); + writeDataToTS(0x20, 0x00 | 0x04); + writeDataToTS(0x21, 0x00 | 0x08); + writeDataToTS(0x22, 0x00 | 0x08); + writeDataToTS(0x23, 0x00 | 0x08); + writeDataToTS(0x24, 0x00 | 0x04); + writeDataToTS(0x25, 0x00 | 0x04); + writeDataToTS(0x26, 0x00 | 0x04); + writeDataToTS(0x27, 0x00 | 0x04); + + } + return temp_return; +} + +void touchClearCurrentDetections() +{ + uint8_t temp_uint; + temp_uint = readDataFromTS(0x05); + temp_uint = readDataFromTS(0x02); + temp_uint = readDataFromTS(0x03); + temp_uint = readDataFromTS(0x04); +} + +uint16_t touchDetectionRoutine() +{ + uint16_t data; + uint8_t temp1, temp2; + + temp1 = readDataFromTS(0x04); + temp2 = readDataFromTS(0x03); + data = temp1; + data = (data << 8) | temp2; + return data; + +} + diff --git a/Touch_Pad_V4.1/Touch_Pad_V4.1.ino b/Touch_Pad_V4.1/Touch_Pad_V4.1.ino index b0cdd1e..7d8571c 100644 --- a/Touch_Pad_V4.1/Touch_Pad_V4.1.ino +++ b/Touch_Pad_V4.1/Touch_Pad_V4.1.ino @@ -99,6 +99,7 @@ //Add any more libraries you need HERE (Serial is included in TouchPad.h at 9600 so this can be used without re-including): #include "KeyboardUK.h" //Edited version of Arduino keyboard library to add backslash key for UK setup, include standard Arduino library for US setup (#include ) #include //Arduino mouse library +#include "USB_HID_Keycodes.h" // support a wide range of keycodes as defined in the USB_HID standard. #include "TouchPad.h" //File required for TouchPad functionality, DO NOT REMOVE! @@ -113,6 +114,8 @@ void keyPress(int x, int y, int commandSet) { //===================================================================== row 0 case 0://Use this case for row 0, column 0, commandSet 1 //Keyboard.println("Hello world"); //EXAMPLE Type Hello World + Keyboard.pressU(KC_ENTER); + Keyboard.releaseAll(); break; //===================================================================== row 1 case 1://Use this case for row 1, column 0, commandSet 1 diff --git a/Touch_Pad_V4.1/USB_HID_Keycodes.cpp b/Touch_Pad_V4.1/USB_HID_Keycodes.cpp new file mode 100644 index 0000000..b4bf189 --- /dev/null +++ b/Touch_Pad_V4.1/USB_HID_Keycodes.cpp @@ -0,0 +1,89 @@ +/* + This code is a minor derivative of the Arduino library Keyboard.cpp + + Copyright (c) 2015, Arduino LLC + Original code (pre-library): Copyright (c) 2011, Peter Barrett + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + ******************************************************************************* + + WARNING: Changing the code in this file could prevent your TouchPad from working! + + *******************************************************************************/ +#include "KeyboardUK.h" +#include "USB_HID_Keycodes.h" +// These U functions, pressU & releaseU operate on raw USB HID codes, +// NOT the KEY_ prefixed ASCII like codes used by the Keyboard/cpp functions. +// The raw USB codes are defined in USB_HID_Keycodes.h, +// They have KC_ & KP_ prefixes for keyboard & keypad codes, +// eg KC_K, KC_F14, KC_LEFTSHIFT, KC_ENTER, KP_1, KP_PLUS +// These U functions are interoperable with the other functions, and +// you should use releaseAll() to finalise a key sequence. + +// pressU() adds the specified key +// to the persistent key report and sends the report. Because of the way +// USB HID works, the host acts like the key remains pressed until we +// call releaseU(), releaseAll(), or otherwise clear the report and resend. +size_t Keyboard_::pressU(uint8_t k) +{ + uint8_t i; + if (k >= 0xE0 && k <= 0xE7) { // it's a modifier key + _keyReport.modifiers |= (1<<(k-0xE0)); + k = 0; + } + + // Add k to the key report only if it's not already present + // and if there is an empty slot. + if (_keyReport.keys[0] != k && _keyReport.keys[1] != k && + _keyReport.keys[2] != k && _keyReport.keys[3] != k && + _keyReport.keys[4] != k && _keyReport.keys[5] != k) { + + for (i=0; i<6; i++) { + if (_keyReport.keys[i] == 0x00) { + _keyReport.keys[i] = k; + break; + } + } + if (i == 6) { + setWriteError(); + return 0; + } + } + sendReport(&_keyReport); + return 1; +} + +// releaseU() takes the specified key out of the persistent key report and +// sends the report. This tells the OS the key is no longer pressed and that +// it shouldn't be repeated any more. +size_t Keyboard_::releaseU(uint8_t k) +{ + uint8_t i; + if (k >= 0xE0 && k <=0xE7) { // it's a modifier key + _keyReport.modifiers &= ~(1<<(k-0xE0)); + k = 0; + } + + // Test the key report to see if k is present. Clear it if it exists. + // Check all positions in case the key is present more than once (which it shouldn't be) + for (i=0; i<6; i++) { + if (0 != k && _keyReport.keys[i] == k) { + _keyReport.keys[i] = 0x00; + } + } + sendReport(&_keyReport); + return 1; +} diff --git a/Touch_Pad_V4.1/USB_HID_Keycodes.h b/Touch_Pad_V4.1/USB_HID_Keycodes.h new file mode 100644 index 0000000..d6335c4 --- /dev/null +++ b/Touch_Pad_V4.1/USB_HID_Keycodes.h @@ -0,0 +1,405 @@ +// USB_HID_Keycodes.h +// +// Unlike the Arduino Keyboard library, which use KEY_ and is sort of ASCII based, +// uses special codes > decimal 127, and translates some codes to the final USB codes, +// these definitions are the actual codes used in the USB HID keyboard/Keypad Page (0x07) +// USB HID Keycodes are derived from: +// http://www.usb.org/developers/hidpage/Hut1_12v2.pdf (starting at page 53) & elsewhere. +// This list is verbose, but in comments the '& KC_...' are reminders of shortened derivatives defined further below, +// KC_ defines a keyboard Key, KP_ defines a keypad Key (including, but more than just, the numeric keypad) +// +#define KC_NOOP 0x00 // Decimal 0 & KC_NO +#define KC_ERRORROLLOVER 0x01 // Decimal 1 & KC_ERO +#define KC_ERRORPOSTFAIL 0x02 // Decimal 2 & KC_EPF +#define KC_UNDEFINED 0x03 // Decimal 3 & KC_UND +#define KC_A 0x04 // Decimal 4 +#define KC_B 0x05 // Decimal 5 +#define KC_C 0x06 // Decimal 6 +#define KC_D 0x07 // Decimal 7 +#define KC_E 0x08 // Decimal 8 +#define KC_F 0x09 // Decimal 9 +#define KC_G 0x0A // Decimal 10 +#define KC_H 0x0B // Decimal 11 +#define KC_I 0x0C // Decimal 12 +#define KC_J 0x0D // Decimal 13 +#define KC_K 0x0E // Decimal 14 +#define KC_L 0x0F // Decimal 15 +#define KC_M 0x10 // Decimal 16 +#define KC_N 0x11 // Decimal 17 +#define KC_O 0x12 // Decimal 18 +#define KC_P 0x13 // Decimal 19 +#define KC_Q 0x14 // Decimal 20 +#define KC_R 0x15 // Decimal 21 +#define KC_S 0x16 // Decimal 22 +#define KC_T 0x17 // Decimal 23 +#define KC_U 0x18 // Decimal 24 +#define KC_V 0x19 // Decimal 25 +#define KC_W 0x1A // Decimal 26 +#define KC_X 0x1B // Decimal 27 +#define KC_Y 0x1C // Decimal 28 +#define KC_Z 0x1D // Decimal 29 +#define KC_1 0x1E // Decimal 30 +#define KC_2 0x1F // Decimal 31 +#define KC_3 0x20 // Decimal 32 +#define KC_4 0x21 // Decimal 33 +#define KC_5 0x22 // Decimal 34 +#define KC_6 0x23 // Decimal 35 +#define KC_7 0x24 // Decimal 36 +#define KC_8 0x25 // Decimal 37 +#define KC_9 0x26 // Decimal 38 +#define KC_0 0x27 // Decimal 39 +#define KC_ENTER 0x28 // Decimal 40 & KC_ENT +#define KC_ESCAPE 0x29 // Decimal 41 & KC_ESC +#define KC_BACKSPACE 0x2A // Decimal 42 & KC_BS +#define KC_TAB 0x2B // Decimal 43 +#define KC_SPACE 0x2C // Decimal 44 & KC_SPA +#define KC_MINUS 0x2D // Decimal 45 & KC_MIN +#define KC_EQUAL 0x2E // Decimal 46 & KC_EQU +#define KC_LEFTBRACKET 0x2F // Decimal 47 & KC_LB +#define KC_RIGHTBRACKET 0x30 // Decimal 48 & KC_RB +#define KC_BACKSLASH 0x31 // Decimal 49 & KC_BSL v's ( BS Back Space) +#define KC_NONUSHASH 0x32 // Decimal 50 & KC_NUH +#define KC_SEMICOLON 0x33 // Decimal 51 & KC_SEM +#define KC_QUOTE 0x34 // Decimal 52 & KC_QUO +#define KC_GRAVE 0x35 // Decimal 53 & KC_GRA +#define KC_COMMA 0x36 // Decimal 54 & KC_COM +#define KC_PERIOD 0x37 // Decimal 55 & KC_PER & KC_DOT +#define KC_SLASH 0x38 // Decimal 56 & KC_SLA +#define KC_CAPSLOCK 0x39 // Decimal 57 & KC_CLK +#define KC_F1 0x3A // Decimal 58 +#define KC_F2 0x3B // Decimal 59 +#define KC_F3 0x3C // Decimal 60 +#define KC_F4 0x3D // Decimal 61 +#define KC_F5 0x3E // Decimal 62 +#define KC_F6 0x3F // Decimal 63 +#define KC_F7 0x40 // Decimal 64 +#define KC_F8 0x41 // Decimal 65 +#define KC_F9 0x42 // Decimal 66 +#define KC_F10 0x43 // Decimal 67 +#define KC_F11 0x44 // Decimal 68 +#define KC_F12 0x45 // Decimal 69 +#define KC_PRINTSCREEN 0x46 // Decimal 70 & KC_PS +#define KC_SCROLLLOCK 0x47 // Decimal 71 & KC_SLK +#define KC_PAUSE 0x48 // Decimal 72 +#define KC_INSERT 0x49 // Decimal 73 & KC_INS +#define KC_HOME 0x4A // Decimal 74 +#define KC_PAGEUP 0x4B // Decimal 75 & KC_PGUP +#define KC_DELETE 0x4C // Decimal 76 & KC_DEL +#define KC_END 0x4D // Decimal 77 +#define KC_PAGEDOWN 0x4E // Decimal 78 & KC_PGDN +#define KC_RIGHTARROW 0x4F // Decimal 79 & KC_RIGHT +#define KC_LEFTARROW 0x50 // Decimal 80 & KC_LEFT +#define KC_DOWNARROW 0x51 // Decimal 81 & KC_DOWN +#define KC_UPARROW 0x52 // Decimal 82 & KC_UP +#define KC_NUMLOCK 0x53 // Decimal 83 & KC_NLK +#define KP_SLASH 0x54 // Decimal 84 & KP_SLA +#define KP_ASTERISK 0x55 // Decimal 85 & KP_AST & KP_STAR +#define KP_MINUS 0x56 // Decimal 86 & KP_MIN +#define KP_PLUS 0x57 // Decimal 87 & KP_PLU +#define KP_ENTER 0x58 // Decimal 88 & KP_ENT +#define KP_1 0x59 // Decimal 89 +#define KP_2 0x5A // Decimal 90 +#define KP_3 0x5B // Decimal 91 +#define KP_4 0x5C // Decimal 92 +#define KP_5 0x5D // Decimal 93 +#define KP_6 0x5E // Decimal 94 +#define KP_7 0x5F // Decimal 95 +#define KP_8 0x60 // Decimal 96 +#define KP_9 0x61 // Decimal 97 +#define KP_0 0x62 // Decimal 98 +#define KP_PERIOD 0x63 // Decimal 99 KP_PER & KP_DOT +#define KC_NONUSBACKSLASH 0x64 // Decimal 100 & KC_NBS +#define KC_APPLICATION 0x65 // Decimal 101 & KC_APP +#define KC_POWER 0x66 // Decimal 102 & KC_POW +#define KP_EQUAL 0x67 // Decimal 103 & KP_EQU +#define KC_F13 0x68 // Decimal 104 +#define KC_F14 0x69 // Decimal 105 +#define KC_F15 0x6A // Decimal 106 +#define KC_F16 0x6B // Decimal 107 +#define KC_F17 0x6C // Decimal 108 +#define KC_F18 0x6D // Decimal 109 +#define KC_F19 0x6E // Decimal 110 +#define KC_F20 0x6F // Decimal 111 +#define KC_F21 0x70 // Decimal 112 +#define KC_F22 0x71 // Decimal 113 +#define KC_F23 0x72 // Decimal 114 +#define KC_F24 0x73 // Decimal 115 +#define KC_EXECUTE 0x74 // Decimal 116 & KC_EXE +#define KC_HELP 0x75 // Decimal 117 +#define KC_MENU 0x76 // Decimal 118 +#define KC_SELECT 0x77 // Decimal 119 & KC_SEL +#define KC_STOP 0x78 // Decimal 120 +#define KC_AGAIN 0x79 // Decimal 121 +#define KC_UNDO 0x7A // Decimal 122 +#define KC_CUT 0x7B // Decimal 123 +#define KC_COPY 0x7C // Decimal 124 +#define KC_PASTE 0x7D // Decimal 125 +#define KC_FIND 0x7E // Decimal 126 +#define KC_MUTE 0x7F // Decimal 127 +#define KC_VOLUMUP 0x80 // Decimal 128 & KC_VU +#define KC_VOLUMEDOWN 0x81 // Decimal 129 & KC_VD +#define KC_LOCKINGCAPS 0x82 // Decimal 130 & KC_LKC +#define KC_LOCKINGNUM 0x83 // Decimal 131 & KC_LKN +#define KC_LOCKINGSCROLL 0x84 // Decimal 132 & KC_LKS +#define KP_COMMA 0x85 // Decimal 133 & KP_COM +#define KP_EQUALAS400 0x86 // Decimal 134 & KP_EQA +#define KC_INTERNATIONAL1 0x87 // Decimal 135 & KC_I1 +#define KC_INTERNATIONAL2 0x88 // Decimal 136 & KC_I2 +#define KC_INTERNATIONAL3 0x89 // Decimal 137 & KC_I3 +#define KC_INTERNATIONAL4 0x8A // Decimal 138 & KC_I4 +#define KC_INTERNATIONAL5 0x8B // Decimal 139 & KC_I5 +#define KC_INTERNATIONAL6 0x8C // Decimal 140 & KC_I6 +#define KC_INTERNATIONAL7 0x8D // Decimal 141 & KC_I7 +#define KC_INTERNATIONAL8 0x8E // Decimal 142 & KC_I8 +#define KC_INTERNATIONAL9 0x8F // Decimal 143 & KC_I9 +#define KC_LANGUAGE1 0x90 // Decimal 144 & KC_L1 +#define KC_LANGUAGE2 0x91 // Decimal 145 & KC_L2 +#define KC_LANGUAGE3 0x92 // Decimal 146 & KC_L3 +#define KC_LANGUAGE4 0x93 // Decimal 147 & KC_L4 +#define KC_LANGUAGE5 0x94 // Decimal 148 & KC_L5 +#define KC_LANGUAGE6 0x95 // Decimal 149 & KC_L6 +#define KC_LANGUAGE7 0x96 // Decimal 150 & KC_L7 +#define KC_LANGUAGE8 0x97 // Decimal 151 & KC_L8 +#define KC_LANGUAGE9 0x98 // Decimal 152 & KC_L9 +#define KC_ALTERASE 0x99 // Decimal 153 & KC_AE +#define KC_SYSREQ 0x9A // Decimal 154 & KC_SR +#define KC_CANCEL 0x9B // Decimal 155 & KC_CAN +#define KC_CLEAR 0x9C // Decimal 156 & KC_CLR +#define KC_PRIOR 0x9D // Decimal 157 & KC_PRI +#define KC_RETURN 0x9E // Decimal 158 & KC_RET +#define KC_SEPARATOR 0x9F // Decimal 159 & KC_SEP +#define KC_OUT 0xA0 // Decimal 160 +#define KC_OPERERATOR 0xA1 // Decimal 161 & KC_OP +#define KC_CLEARAGAIN 0xA2 // Decimal 162 & KC_CA +#define KC_CLEARSELECT 0xA3 // Decimal 163 & KC_CS +#define KC_EXTENDEDSELECT 0xA4 // Decimal 164 & KC_ES +#define RESERVED_0xA5 0xA5 // Decimal 165 +#define RESERVED_0xA6 0xA6 // Decimal 166 +#define RESERVED_0xA7 0xA7 // Decimal 167 +#define RESERVED_0xA8 0xA8 // Decimal 168 +#define RESERVED_0xA9 0xA9 // Decimal 169 +#define RESERVED_0xAA 0xAA // Decimal 170 +#define RESERVED_0xAB 0xAB // Decimal 171 +#define RESERVED_0xAC 0xAC // Decimal 172 +#define RESERVED_0xAD 0xAD // Decimal 173 +#define RESERVED_0xAE 0xAE // Decimal 174 +#define RESERVED_0xAF 0xAF // Decimal 175 +#define KP_00 0xB0 // Decimal 176 +#define KP_000 0xB1 // Decimal 177 +#define KC_THOUSANDSSEPARATOR 0xB2 // Decimal 178 & KC_TS +#define KC_DECIMALSEPARATOR 0xB3 // Decimal 179 & KC_DS +#define KC_CURRENCYUNIT 0xB4 // Decimal 180 & KC_CU +#define KC_CURRENCYSUBUNIT 0xB5 // Decimal 181 & KC_CSU +#define KP_LEFTPARENTHESIS 0xB6 // Decimal 182 & KP_LPAR +#define KP_RIGHTPARENTHESIS 0xB7 // Decimal 183 & KP_RPAR +#define KP_LEFTBRACE 0xB8 // Decimal 184 & KP_LBR +#define KP_RIGHTBRACE 0xB9 // Decimal 185 & KP_RBR +#define KP_TAB 0xBA // Decimal 186 +#define KP_BACKSPACE 0xBB // Decimal 187 & KP_BS +#define KP_A 0xBC // Decimal 188 +#define KP_B 0xBD // Decimal 189 +#define KP_C 0xBE // Decimal 190 +#define KP_D 0xBF // Decimal 191 +#define KP_E 0xC0 // Decimal 192 +#define KP_F 0xC1 // Decimal 193 +#define KP_XOR 0xC2 // Decimal 194 +#define KP_CARRET 0xC3 // Decimal 195 & KP_HAT +#define KP_PERCENT 0xC4 // Decimal 196 & KP_PER +#define KP_LESSTHAN 0xC5 // Decimal 197 & KP_LT +#define KP_GREATERTHAN 0xC6 // Decimal 198 & KP_GT +#define KP_AMPERSAND 0xC7 // Decimal 199 & KP_AMP +#define KP_AMPERSAND2 0xC8 // Decimal 200 & KP_AMP2 +#define KP_VERTICALBAR 0xC9 // Decimal 201 & KP_BAR,PIPE +#define KP_VERTICALBAR2 0xCA // Decimal 202 & KP_BAR2,PIPE2 +#define KP_COLON 0xCB // Decimal 203 +#define KP_HASH 0xCC // Decimal 204 +#define KP_SPACE 0xCD // Decimal 205 & KP_SPA +#define KP_COMMERCIALAT 0xCE // Decimal 206 & KP_AT +#define KP_EXCLAMATION 0xCF // Decimal 207 & KP_EX +#define KP_MEMORYSTORE 0xD0 // Decimal 208 & KP_MST +#define KP_MEMORYRECALL 0xD1 // Decimal 209 & KP_MRE +#define KP_MEMORYCLEAR 0xD2 // Decimal 210 & KP_MCL +#define KP_MEMORYADD 0xD3 // Decimal 211 & KP_MAD +#define KP_MEMORYSUB 0xD4 // Decimal 212 & KP_MSU +#define KP_MEMORYMUL 0xD5 // Decimal 213 & KP_MMU +#define KP_MEMORYDIV 0xD6 // Decimal 214 & KP_MDI +#define KP_PLUSMINUS 0xD7 // Decimal 215 & KP_PM +#define KP_CLEAR 0xD8 // Decimal 216 & KP_CLR +#define KP_CLEARENTRY 0xD9 // Decimal 217 & KP_CE +#define KP_BINARY 0xDA // Decimal 218 & KP_BIN +#define KP_OCTAL 0xDB // Decimal 219 & KP_OCT +#define KP_DECIMAL 0xDC // Decimal 220 & KP_DEC +#define KP_HEXADECIMAL 0xDD // Decimal 221 & KP_HEX +#define RESERVED_0xDE 0xDE // Decimal 222 +#define RESERVED_0xDF 0xDF // Decimal 223 +// Modifiers +#define KC_LEFTCONTROL 0xE0 // Decimal 224 & KC_LC +#define KC_LEFTSHIFT 0xE1 // Decimal 225 & KC_LS +#define KC_LEFTALT 0xE2 // Decimal 226 & KC_LA +#define KC_LEFTGUI 0xE3 // Decimal 227 & KC_LG +#define KC_RIGHTCONTROL 0xE4 // Decimal 228 & KC_RC +#define KC_RIGHTSHIFT 0xE5 // Decimal 229 & KC_RS +#define KC_RIGHTALT 0xE6 // Decimal 230 & KC_RA +#define KC_RIGHTGUI 0xE7 // Decimal 231 & KC_RG +// +#define RESERVED_0xE8 0xE8 // Decimal 232 +#define RESERVED_0xE9 0xE9 // Decimal 233 +#define RESERVED_0xEA 0xEA // Decimal 234 +#define RESERVED_0xEB 0xEB // Decimal 235 +#define RESERVED_0xEC 0xEC // Decimal 236 +#define RESERVED_0xED 0xED // Decimal 237 +#define RESERVED_0xEE 0xEE // Decimal 238 +#define RESERVED_0xEF 0xEF // Decimal 239 +#define RESERVED_0xF0 0xF0 // Decimal 240 +#define RESERVED_0xF1 0xF1 // Decimal 241 +#define RESERVED_0xF2 0xF2 // Decimal 242 +#define RESERVED_0xF3 0xF3 // Decimal 243 +#define RESERVED_0xF4 0xF4 // Decimal 244 +#define RESERVED_0xF5 0xF5 // Decimal 245 +#define RESERVED_0xF6 0xF6 // Decimal 246 +#define RESERVED_0xF7 0xF7 // Decimal 247 +#define RESERVED_0xF8 0xF8 // Decimal 248 +#define RESERVED_0xF9 0xF9 // Decimal 249 +#define RESERVED_0xFA 0xFA // Decimal 250 +#define RESERVED_0xFB 0xFB // Decimal 251 +#define RESERVED_0xFC 0xFC // Decimal 252 +#define RESERVED_0xFD 0xFD // Decimal 253 +#define RESERVED_0xFE 0xFE // Decimal 254 +#define KC_LASTCODE 0xFF // Decimal 255 // Also Reserved +// + +// Abbreviated keycodes. +// With exceptions like the well known PGDN, PGUP, LEFT, RIGHT, UP, DOWN, these generally are; +// first letters where the verbose is two words, eg KC_EXTENDEDSELECT is KC_ES, +// the first three letters. eg KC_SEMICOLON is KC_SEM, KC_SELECT is KC_SEL, +// or, just made up. +// Not every key has an abbreviation. If you make up a new one, make sure it doesn't conflict. +// +// KC_ defines a keyboard Key, KP_ defines a keypad Key (including, but more than just, the numeric keypad) +// +#define KC_NO 0x00 // Decimal 0 & KC_NOOP +#define KC_ERO 0x01 // Decimal 1 & KC_ERRORROLLOVER +#define KC_EPF 0x02 // Decimal 2 & KC_ERRORPOSTFAIL +#define KC_UND 0x03 // Decimal 3 & KC_UNDEFINED +#define KC_ENT 0x28 // Decimal 40 & KC_ENTER +#define KC_ESC 0x29 // Decimal 41 & KC_ESCAPE +#define KC_BS 0x2A // Decimal 42 & KC_BACKSPACE +#define KC_SPA 0x2C // Decimal 44 & KC_SPACE +#define KC_MIN 0x2D // Decimal 45 & KC_MINUS +#define KC_EQU 0x2E // Decimal 46 & KC_EQUAL +#define KC_LB 0x2F // Decimal 47 & KC_LEFTBRACKET +#define KC_RB 0x30 // Decimal 48 & KC_RIGHTBRACKET +#define KC_BSL 0x31 // Decimal 49 & KC_BACKSLASH +#define KC_NUH 0x32 // Decimal 50 & KC_NONUSHASH +#define KC_SEM 0x33 // Decimal 51 & KC_SEMICOLON +#define KC_QUO 0x34 // Decimal 52 & KC_QUOTE +#define KC_GRA 0x35 // Decimal 53 & KC_GRAVE +#define KC_COM 0x36 // Decimal 54 & KC_COMMA +#define KC_PER 0x37 // Decimal 55 & KC_PERIOD & KC_DOT +#define KC_DOT 0x37 // Decimal 55 & KC_PERIOD & KC_PER +#define KC_SLA 0x38 // Decimal 56 & KC_SLASH +#define KC_CLK 0x39 // Decimal 57 & KC_CAPSLOCK +#define KC_PS 0x46 // Decimal 70 & KC_PRINTSCREEN +#define KC_SLK 0x47 // Decimal 71 & KC_SCROLLLOCK +#define KC_INS 0x49 // Decimal 73 & KC_INSERT +#define KC_PGUP 0x4B // Decimal 75 & KC_PAGEUP +#define KC_DEL 0x4C // Decimal 76 & KC_DELETE +#define KC_PGDN 0x4E // Decimal 78 & KC_PAGEDOWN +#define KC_RIGHT 0x4F // Decimal 79 & KC_RIGHTARROW +#define KC_LEFT 0x50 // Decimal 80 & KC_LEFTARROW +#define KC_DOWN 0x51 // Decimal 81 & KC_DOWNARROW +#define KC_UP 0x52 // Decimal 82 & KC_UPARROW +#define KC_NLK 0x53 // Decimal 83 & KC_NUMLOCK +#define KP_SLA 0x54 // Decimal 84 & KP_SLASH +#define KP_AST 0x55 // Decimal 85 & KP_ASTERISK & KP_STAR +#define KP_STAR 0x55 // Decimal 85 & KP_ASTERISK & KP_AST +#define KP_MIN 0x56 // Decimal 86 & KP_MINUS +#define KP_PLU 0x57 // Decimal 87 & KP_PLUS +#define KP_ENT 0x58 // Decimal 88 & KP_ENTER +#define KC_NBS 0x64 // Decimal 100 & KC_NONUSBACKSLASH +#define KC_APP 0x65 // Decimal 101 & KC_APPLICATION +#define KC_POW 0x66 // Decimal 102 & KC_POWER +#define KP_EQU 0x67 // Decimal 103 & KP_EQUAL +#define KC_EXE 0x74 // Decimal 116 & KC_EXECUTE +#define KC_SEL 0x77 // Decimal 119 & KC_SELECT +#define KC_VU 0x80 // Decimal 128 & KC_VOLUMUP +#define KC_VD 0x81 // Decimal 129 & KC_VOLUMEDOWN +#define KC_LKC 0x82 // Decimal 130 & KC_LOCKINGCAPS +#define KC_LKN 0x83 // Decimal 131 & KC_LOCKINGNUM +#define KC_LKS 0x84 // Decimal 132 & KC_LOCKINGSCROLL +#define KP_COM 0x85 // Decimal 133 & KP_COMMA +#define KP_EQA 0x86 // Decimal 134 & KP_EQUALAS400 +#define KC_I1 0x87 // Decimal 135 & KC_INTERNATIONAL1 +#define KC_I2 0x88 // Decimal 136 & KC_INTERNATIONAL2 +#define KC_I3 0x89 // Decimal 137 & KC_INTERNATIONAL3 +#define KC_I4 0x8A // Decimal 138 & KC_INTERNATIONAL4 +#define KC_I5 0x8B // Decimal 139 & KC_INTERNATIONAL5 +#define KC_I6 0x8C // Decimal 140 & KC_INTERNATIONAL6 +#define KC_I7 0x8D // Decimal 141 & KC_INTERNATIONAL7 +#define KC_I8 0x8E // Decimal 142 & KC_INTERNATIONAL8 +#define KC_I9 0x8F // Decimal 143 & KC_INTERNATIONAL9 +#define KC_L1 0x90 // Decimal 144 & KC_LANGUAGE1 +#define KC_L2 0x91 // Decimal 145 & KC_LANGUAGE2 +#define KC_L3 0x92 // Decimal 146 & KC_LANGUAGE3 +#define KC_L4 0x93 // Decimal 147 & KC_LANGUAGE4 +#define KC_L5 0x94 // Decimal 148 & KC_LANGUAGE5 +#define KC_L6 0x95 // Decimal 149 & KC_LANGUAGE6 +#define KC_L7 0x96 // Decimal 150 & KC_LANGUAGE7 +#define KC_L8 0x97 // Decimal 151 & KC_LANGUAGE8 +#define KC_L9 0x98 // Decimal 152 & KC_LANGUAGE9 +#define KC_AE 0x99 // Decimal 153 & KC_ALTERASE +#define KC_SR 0x9A // Decimal 154 & KC_SYSREQ +#define KC_CAN 0x9B // Decimal 155 & KC_CANCEL +#define KC_CLR 0x9C // Decimal 156 & KC_CLEAR +#define KC_PRI 0x9D // Decimal 157 & KC_PRIOR +#define KC_RET 0x9E // Decimal 158 & KC_RETURN +#define KC_SEP 0x9F // Decimal 159 & KC_SEPARATOR +#define KC_OP 0xA1 // Decimal 161 & KC_OPERERATOR +#define KC_CA 0xA2 // Decimal 162 & KC_CLEARAGAIN +#define KC_CS 0xA3 // Decimal 163 & KC_CLEARSELECT +#define KC_ES 0xA4 // Decimal 164 & KC_EXTENDEDSELECT +#define KC_TS 0xB2 // Decimal 178 & KC_THOUSANDSSEPARATOR +#define KC_DS 0xB3 // Decimal 179 & KC_DECIMALSEPARATOR +#define KC_CU 0xB4 // Decimal 180 & KC_CURRENCYUNIT +#define KC_CSU 0xB5 // Decimal 181 & KC_CURRENCYSUBUNIT +#define KP_LPAR 0xB6 // Decimal 182 & KP_LEFTPARENTHESIS +#define KP_RPAR 0xB7 // Decimal 183 & KP_RIGHTPARENTHESIS +#define KP_LBR 0xB8 // Decimal 184 & KP_LEFTBRACE +#define KP_RBR 0xB9 // Decimal 185 & KP_RIGHTBRACE +#define KP_BS 0xBB // Decimal 187 & KP_BACKSPACE +#define KP_HAT 0xC3 // Decimal 195 & KP_CARRET +#define KP_PER 0xC4 // Decimal 196 & KP_PERCENT +#define KP_LT 0xC5 // Decimal 197 & KP_LESSTHAN +#define KP_GT 0xC6 // Decimal 198 & KP_GREATERTHAN +#define KP_AMP 0xC7 // Decimal 199 & KP_AMPERSAND +#define KP_AMP2 0xC8 // Decimal 200 & KP_AMPERSAND2 +#define KP_BAR 0xC9 // Decimal 201 & KP_VERTICALBAR & KP_PIPE +#define KP_PIPE 0xC9 // Decimal 201 & KP_VERTICALBAR & KP_BAR +#define KP_BAR2 0xCA // Decimal 202 & KP_VERTICALBAR2 & KP_PIPE2 +#define KP_PIPE2 0xCA // Decimal 202 & KP_VERTICALBAR2 & KP_BAR2 +#define KP_SPA 0xCD // Decimal 205 & KP_SPACE +#define KP_AT 0xCE // Decimal 206 & KP_COMMERCIALAT +#define KP_EX 0xCF // Decimal 207 & KP_EXCLAMATION +#define KP_MST 0xD0 // Decimal 208 & KP_MEMORYSTORE +#define KP_MRE 0xD1 // Decimal 209 & KP_MEMORYRECALL +#define KP_MCL 0xD2 // Decimal 210 & KP_MEMORYCLEAR +#define KP_MAD 0xD3 // Decimal 211 & KP_MEMORYADD +#define KP_MSU 0xD4 // Decimal 212 & KP_MEMORYSUB +#define KP_MMU 0xD5 // Decimal 213 & KP_MEMORYMUL +#define KP_MDI 0xD6 // Decimal 214 & KP_MEMORYDIV +#define KP_PM 0xD7 // Decimal 215 & KP_PLUSMINUS +#define KP_CLR 0xD8 // Decimal 216 & KP_CLEAR +#define KP_CE 0xD9 // Decimal 217 & KP_CLEARENTRY +#define KP_BIN 0xDA // Decimal 218 & KP_BINARY +#define KP_OCT 0xDB // Decimal 219 & KP_OCTAL +#define KP_DEC 0xDC // Decimal 220 & KP_DECIMAL +#define KP_HEX 0xDD // Decimal 221 & KP_HEXADECIMAL +// Modifiers +#define KC_LC 0xE0 // Decimal 224 & KC_LEFTCONTROL +#define KC_LS 0xE1 // Decimal 225 & KC_LEFTSHIFT +#define KC_LA 0xE2 // Decimal 226 & KC_LEFTALT +#define KC_LG 0xE3 // Decimal 227 & KC_LEFTGUI +#define KC_RC 0xE4 // Decimal 228 & KC_RIGHTCONTROL +#define KC_RS 0xE5 // Decimal 229 & KC_RIGHTSHIFT +#define KC_RA 0xE6 // Decimal 230 & KC_RIGHTALT +#define KC_RG 0xE7 // Decimal 231 & KC_RIGHTGUI