├── .codespell ├── exclude-file.txt └── ignore-words.txt ├── .codespellrc ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.yml │ ├── config.yml │ └── feature_request.md └── workflows │ └── githubci.yml ├── .pre-commit-config.yaml ├── LICENSE ├── README.md ├── examples └── ik_translator │ ├── .feather_rp2040_usbhost_tinyusb.generate │ └── ik_translator.ino ├── intellikeys enumerate-download-reenumerate.tdc ├── library.properties └── src ├── Adafruit_IntelliKeys.cpp ├── Adafruit_IntelliKeys.h ├── IKModifier.cpp ├── IKModifier.h ├── IKOverlay.cpp ├── IKOverlay.h ├── IKSettings.cpp ├── IKSettings.h ├── IKUniversal.h ├── ik_firmware.h ├── ik_loader.h └── intellikeysdefs.h /.codespell/exclude-file.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/Adafruit_IntelliKeys/afd23a892c4b3e187de99fdf2c738f058d11ea3b/.codespell/exclude-file.txt -------------------------------------------------------------------------------- /.codespell/ignore-words.txt: -------------------------------------------------------------------------------- 1 | synopsys 2 | sie 3 | inout 4 | busses 5 | bloaded 6 | nd 7 | -------------------------------------------------------------------------------- /.codespellrc: -------------------------------------------------------------------------------- 1 | # See: https://github.com/codespell-project/codespell#using-a-config-file 2 | [codespell] 3 | # In the event of a false positive, add the problematic word, in all lowercase, to 'ignore-words.txt' (one word per line). 4 | # Or copy & paste the whole problematic line to 'exclude-file.txt' 5 | ignore-words = .codespell/ignore-words.txt 6 | exclude-file = .codespell/exclude-file.txt 7 | check-filenames = 8 | check-hidden = 9 | count = 10 | skip = .git 11 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.yml: -------------------------------------------------------------------------------- 1 | name: Bug Report 2 | description: Report a problem with TinyUSB Library 3 | labels: 'Bug' 4 | body: 5 | - type: markdown 6 | attributes: 7 | value: | 8 | Thanks for taking the time to fill out this bug report! 9 | It's okay to leave some blank if it doesn't apply to your problem. 10 | 11 | - type: dropdown 12 | attributes: 13 | label: Operating System 14 | options: 15 | - Linux 16 | - MacOS 17 | - RaspberryPi OS 18 | - Windows 7 19 | - Windows 10 20 | - Windows 11 21 | - Others 22 | validations: 23 | required: true 24 | 25 | - type: input 26 | attributes: 27 | label: Arduino IDE version 28 | placeholder: e.g Arduino 1.8.15 29 | validations: 30 | required: true 31 | 32 | - type: input 33 | attributes: 34 | label: Board 35 | placeholder: e.g Feather nRF52840 Express 36 | validations: 37 | required: true 38 | 39 | - type: input 40 | attributes: 41 | label: ArduinoCore version 42 | description: Can be found under "Board Manager" menu 43 | validations: 44 | required: true 45 | 46 | - type: input 47 | attributes: 48 | label: TinyUSB Library version 49 | placeholder: "Release version or github latest" 50 | validations: 51 | required: true 52 | 53 | - type: textarea 54 | attributes: 55 | label: Sketch as ATTACHED TXT 56 | placeholder: | 57 | e.g examples/MassStorage/msc_ramdisk. 58 | If it is custom sketch, please provide it as **ATTACHED** files or link to it. 59 | Pasting raw long code that hurts readability can get your issue **closed** 60 | validations: 61 | required: true 62 | 63 | - type: textarea 64 | attributes: 65 | label: Compiled Log as ATTACHED TXT 66 | placeholder: | 67 | Compiled log from Arduino IDE as **ATTACHED** txt. 68 | Pasting raw long log that hurts readability can get your issue **closed** 69 | validations: 70 | required: true 71 | 72 | - type: textarea 73 | attributes: 74 | label: What happened ? 75 | placeholder: A clear and concise description of what the bug is. 76 | validations: 77 | required: true 78 | 79 | - type: textarea 80 | attributes: 81 | label: How to reproduce ? 82 | placeholder: | 83 | 1. Go to '...' 84 | 2. Click on '....' 85 | 3. See error 86 | validations: 87 | required: true 88 | 89 | - type: textarea 90 | attributes: 91 | label: Debug Log 92 | placeholder: | 93 | TinyUSB debug log where the issue occurred as attached txt file, best with comments to explain the actual events. 94 | validations: 95 | required: false 96 | 97 | - type: textarea 98 | attributes: 99 | label: Screenshots 100 | description: If applicable, add screenshots to help explain your problem. 101 | validations: 102 | required: false 103 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: Adafruit Support Forum 4 | url: https://forums.adafruit.com 5 | about: If you have other questions or need help, post it here. 6 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: 'Feature' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/workflows/githubci.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | 3 | on: 4 | pull_request: 5 | push: 6 | repository_dispatch: 7 | release: 8 | types: 9 | - created 10 | 11 | concurrency: 12 | group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} 13 | cancel-in-progress: true 14 | 15 | jobs: 16 | pre-commit: 17 | runs-on: ubuntu-latest 18 | steps: 19 | - name: Setup Python 20 | uses: actions/setup-python@v4 21 | with: 22 | python-version: '3.x' 23 | 24 | - name: Checkout code 25 | uses: actions/checkout@v3 26 | 27 | - name: Run pre-commit 28 | uses: pre-commit/action@v3.0.0 29 | 30 | # - name: Checkout adafruit/ci-arduino 31 | # uses: actions/checkout@v3 32 | # with: 33 | # repository: adafruit/ci-arduino 34 | # path: ci 35 | 36 | # - name: pre-install 37 | # run: bash ci/actions_install.sh 38 | 39 | # - name: doxygen 40 | # env: 41 | # GH_REPO_TOKEN: ${{ secrets.GH_REPO_TOKEN }} 42 | # PRETTYNAME : "Adafruit IntelliKeys" 43 | # run: bash ci/doxy_gen_and_deploy.sh 44 | 45 | build: 46 | runs-on: ubuntu-latest 47 | strategy: 48 | fail-fast: false 49 | matrix: 50 | board: 51 | # RP2040 52 | - 'feather_rp2040_usbhost_tinyusb' 53 | 54 | steps: 55 | - name: Setup Python 56 | uses: actions/setup-python@v4 57 | with: 58 | python-version: '3.x' 59 | 60 | - name: Checkout code 61 | uses: actions/checkout@v3 62 | 63 | - name: Checkout adafruit/ci-arduino 64 | uses: actions/checkout@v3 65 | with: 66 | repository: adafruit/ci-arduino 67 | path: ci 68 | 69 | - name: pre-install 70 | run: bash ci/actions_install.sh 71 | 72 | - name: test platforms 73 | run: | 74 | python3 ci/build_platform.py ${{ matrix.board }} 75 | tree examples/ik_translator 76 | cp examples/ik_translator/build/*/ik_translator.ino.uf2 ik_translator-${{ matrix.board }}.uf2 77 | 78 | - uses: actions/upload-artifact@v4 79 | with: 80 | name: ik_translator-${{ matrix.board }} 81 | path: ik_translator-${{ matrix.board }}.uf2 82 | 83 | - name: Prepare Release Asset 84 | if: ${{ github.event_name == 'release' }} 85 | run: | 86 | cp ik_translator-${{ matrix.board }}.uf2 ik_translator-${{ matrix.board }}-${{ github.event.release.tag_name }}.uf2 87 | 88 | - name: Upload Release Asset 89 | uses: softprops/action-gh-release@v1 90 | if: ${{ github.event_name == 'release' }} 91 | with: 92 | files: ik_translator-${{ matrix.board }}-${{ github.event.release.tag_name }}.uf2 93 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2020 Diego Elio Pettenò 2 | # 3 | # SPDX-License-Identifier: Unlicense 4 | 5 | repos: 6 | - repo: https://github.com/pre-commit/pre-commit-hooks 7 | rev: v4.4.0 8 | hooks: 9 | - id: check-yaml 10 | - id: trailing-whitespace 11 | - id: end-of-file-fixer 12 | - id: forbid-submodules 13 | 14 | - repo: https://github.com/pre-commit/mirrors-clang-format 15 | rev: v15.0.7 16 | hooks: 17 | - id: clang-format 18 | exclude: ^(src/ik_firmware.h|src/ik_loader.h) 19 | types_or: [c++, c, header] 20 | 21 | - repo: https://github.com/codespell-project/codespell 22 | rev: v2.2.4 23 | hooks: 24 | - id: codespell 25 | args: [-w] 26 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Adafruit Industries 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Adafruit IntelliKeys 2 | 3 | Adafruit IntelliKeys USB Translator uses both TinyUSB device and host stacks on 2 USB ports of rp2040 where: 4 | 5 | - Native USB is running as device 6 | - PICO-PIO-USB is running as host 7 | 8 | USB host will enumerate IntelliKeys, download ez-usb firmware and then operate as host driver including scanning overlay sensor, membrane matrix and switch, set LEDs and buzzer etc... then translate corresponding key events to standard USB keyboard/mouse to the PC host via device interface. 9 | 10 | ## Supported Hardware 11 | 12 | This library supports the following hardware: 13 | 14 | - [Adafruit Feather RP2040 with USB Type A Host](https://www.adafruit.com/product/5723) 15 | 16 | ## Features 17 | 18 | This library tries to support all features of the original IntelliKeys USB driver. The following features are supported: 19 | 20 | - Download ez-usb firmware from USB host 21 | - IntelliKeys overlay detection with LEDs and sound indicator 22 | - Support all standard overlays (except setup) with both keyboard and mouse. 23 | - Support all modifier latching for keys like shift, ctrl, alt, command/win/super 24 | - Support toggle (on/off) switch detection (yellow LED) 25 | - Support custom overlays but required re-compiled firmware with new overlay definition. 26 | 27 | TODO (not supported yet): 28 | 29 | - Switch is not supported due to lack of testing hardware 30 | - Multiple reports event such as: keystrokes like www. and .com and mouse double clicks 31 | - Support setup overlays for behavior settings (volume, repeat rate, mouse speed). Maybe stores settings in text file (exposed by MSC) 32 | - Custom overlays in text file in MSC 33 | 34 | ## Build and Flash 35 | 36 | ### Compiling from source 37 | 38 | - Install [arduino-pico](https://github.com/earlephilhower/arduino-pico) 39 | - Open examples/ik_translater, from IDE menu then select following option 40 | 41 | ``` 42 | Board: Adafruit Feather RP2040 USB Host 43 | CPU Speed: 120 MHz 44 | USB Stack: Adafruit TinyUSB 45 | ``` 46 | - Compile and upload 47 | 48 | ### Using pre-built UF2 49 | 50 | - Put board to DFU mode by pressing BOOTSEL button and then reset button 51 | - Download UF2 from release page and copy to the board 52 | 53 | ## Usage 54 | 55 | - When powering on or without IKey device, neopixel will be red. Plugging IKey into USB host connector, neopixel will be yellow to indicate that IKey firmware is downloading and then green when ready. Note: it will briefly show red when device is re-enumerated. 56 | - Toggle IKeys on/off switch will play beep sound and change neopixel from green (on) to yellow (off) or vice versa. 57 | - After IKey firmware is ready, we will initialize IKey device and then start scanning photo sensors for overlay. If overlay changes is detected, we will play a long beep sound and flash device LEDs. 58 | - If overlay is detected, we will scan membrane matrix and switch. If any key is pressed, there is a short beep sound as well as neopixel color set to blue (key pressed) or green (key released) for indicator. 59 | - All membrane and switch changes will be accumulated using an 2-dimension array, which should be poll regularly (2-8ms) and then translated to standard USB keyboard/mouse events according to overlay data. If there is any change, we will send a report to PC. 60 | - All modifier keys: Control, Shift, Alt/Option, Command/Windows/Super are latching key, which means they will retain their state until they are pressed again. IKeys LEDs will also bet set accordingly. 61 | - Custom overlays are supported, however, it requires re-compiled firmware with new overlay definition. For how to define an overlay, check out `src/overlay.h` and `src/overlay.c` for details. All custom overlay number must start from 8 since 0-7 is reserved for standard overlays. 62 | 63 | ## References 64 | 65 | - https://github.com/ATMakersOrg/OpenIKeys 66 | - https://github.com/gdsports/IntelliKeys_uhls 67 | -------------------------------------------------------------------------------- /examples/ik_translator/.feather_rp2040_usbhost_tinyusb.generate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/Adafruit_IntelliKeys/afd23a892c4b3e187de99fdf2c738f058d11ea3b/examples/ik_translator/.feather_rp2040_usbhost_tinyusb.generate -------------------------------------------------------------------------------- /examples/ik_translator/ik_translator.ino: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | Adafruit invests time and resources providing this open source code, 3 | please support Adafruit and open-source hardware by purchasing 4 | products from Adafruit! 5 | 6 | MIT license, check LICENSE for more information 7 | Copyright (c) 2019 Ha Thach for Adafruit Industries 8 | All text above, and the splash screen below must be included in 9 | any redistribution 10 | *********************************************************************/ 11 | 12 | /* This example demonstrates use of both device and host, where 13 | * - Device run on native usb controller (controller0) 14 | * - Host run on bit-banging 2 GPIOs with the help of Pico-PIO-USB library 15 | * (controller1) 16 | * 17 | * Example sketch receive keyboard report from host interface (from e.g consumer 18 | * keyboard) and remap it to another key and send it via device interface (to 19 | * PC). For simplicity, this example only toggle shift key to the report, 20 | * effectively remap: 21 | * - all character key <-> upper case 22 | * - number <-> its symbol (with shift) 23 | * 24 | * Requirements: 25 | * - [Pico-PIO-USB](https://github.com/sekigon-gonnoc/Pico-PIO-USB) library 26 | * - 2 consecutive GPIOs: D+ is defined by PIN_USB_HOST_DP, D- = D+ +1 27 | * - Provide VBus (5v) and GND for peripheral 28 | * - CPU Speed must be either 120 or 240 Mhz. Selected via "Menu -> CPU Speed" 29 | */ 30 | 31 | // pio-usb is required for rp2040 host 32 | #include "pio_usb.h" 33 | 34 | #include "Adafruit_TinyUSB.h" 35 | 36 | #include "Adafruit_IntelliKeys.h" 37 | 38 | // Pin D+ for host, D- = D+ + 1 39 | #ifndef PIN_USB_HOST_DP 40 | #define PIN_USB_HOST_DP 16 // 20 41 | #endif 42 | 43 | // Pin for enabling Host VBUS. comment out if not used 44 | #ifndef PIN_5V_EN 45 | #define PIN_5V_EN 18 // 22 46 | #endif 47 | 48 | #ifndef PIN_5V_EN_STATE 49 | #define PIN_5V_EN_STATE 1 50 | #endif 51 | 52 | #ifndef PIN_NEOPIXEL 53 | #define PIN_NEOPIXEL 21 54 | #endif 55 | 56 | #ifndef NEOPIXEL_POWER 57 | #define NEOPIXEL_POWER 20 58 | #endif 59 | 60 | #define SCAN_INTERVAL 8 61 | 62 | // USB Host object 63 | Adafruit_USBH_Host USBHost; 64 | 65 | Adafruit_IntelliKeys IKeys; 66 | 67 | // HID report descriptor for keyboard and mouse 68 | // Single Report (no ID) descriptor 69 | uint8_t const desc_keyboard_report[] = {TUD_HID_REPORT_DESC_KEYBOARD()}; 70 | uint8_t const desc_mouse_report[] = {TUD_HID_REPORT_DESC_MOUSE()}; 71 | 72 | // USB HID object. For ESP32 these values cannot be changed after this 73 | // declaration desc report, desc len, protocol, interval, use out endpoint 74 | Adafruit_USBD_HID usb_keyboard(desc_keyboard_report, 75 | sizeof(desc_keyboard_report), 76 | HID_ITF_PROTOCOL_KEYBOARD, 8, false); 77 | 78 | Adafruit_USBD_HID usb_mouse(desc_mouse_report, sizeof(desc_mouse_report), 79 | HID_ITF_PROTOCOL_MOUSE, 8, false); 80 | 81 | //------------- prototypes -------------// 82 | enum { PIXEL_BRIGHTNESS = 0x20 }; 83 | 84 | enum { 85 | COLOR_NO_USB = 0xff0000, 86 | COLOR_NOT_READY = 0xffff00, 87 | COLOR_READY = 0x00ff00, 88 | COLOR_KEY_PRESSED = 0x0000ff 89 | }; 90 | 91 | void setPixel(uint32_t color); 92 | 93 | //--------------------------------------------------------------------+ 94 | // Setup and Loop on Core0 95 | //--------------------------------------------------------------------+ 96 | 97 | void setup() { 98 | Serial.begin(115200); 99 | usb_keyboard.begin(); 100 | usb_mouse.begin(); 101 | 102 | // Enable neopixel power 103 | pinMode(NEOPIXEL_POWER, OUTPUT); 104 | digitalWrite(NEOPIXEL_POWER, HIGH); 105 | 106 | pinMode(PIN_NEOPIXEL, OUTPUT); 107 | digitalWrite(PIN_NEOPIXEL, LOW); 108 | setPixel(0); 109 | delay(1); 110 | 111 | setPixel(COLOR_NO_USB); 112 | 113 | // while ( !Serial ) delay(10); // wait for native usb 114 | Serial.println("IntelliKeys USB Adapter"); 115 | } 116 | 117 | bool hasKeyboardReport(hid_keyboard_report_t const *report) { 118 | if (report->modifier != 0) { 119 | return true; 120 | } 121 | 122 | for (uint8_t i = 0; i < 6; i++) { 123 | if (report->keycode[i] != 0) { 124 | return true; 125 | } 126 | } 127 | 128 | return false; 129 | } 130 | 131 | void scanMembraneAndSwitch(void) { 132 | static hid_keyboard_report_t kb_prev_report = {0, 0, {0}}; 133 | static bool kb_has_prev_report = false; 134 | static uint8_t mouse_prev_buttons = 0; 135 | 136 | if (!IKeys.isAttached()) { 137 | setPixel(COLOR_NO_USB); 138 | return; 139 | } 140 | 141 | if (!IKeys.IsOpen() || !IKeys.IsSwitchedOn()) { 142 | setPixel(COLOR_NOT_READY); 143 | return; 144 | } 145 | 146 | uint32_t color = COLOR_READY; 147 | 148 | hid_keyboard_report_t kb_report; 149 | hid_mouse_report_t mouse_report; 150 | 151 | IKeys.getHIDReport(&kb_report, &mouse_report); 152 | 153 | //------------- Keyboard -------------// 154 | bool new_kb_report = hasKeyboardReport(&kb_report); 155 | 156 | if (new_kb_report) { 157 | if (memcmp(&kb_prev_report, &kb_report, sizeof(kb_report))) { 158 | // send only if kb_report is changed since last time 159 | usb_keyboard.sendReport(0, &kb_report, sizeof(kb_report)); 160 | } 161 | kb_has_prev_report = true; 162 | color = COLOR_KEY_PRESSED; 163 | } else { 164 | if (kb_has_prev_report) { 165 | // has previous report before, send empty kb_report to release all keys 166 | hid_keyboard_report_t null_report = {0, 0, {0}}; 167 | usb_keyboard.sendReport(0, &null_report, sizeof(null_report)); 168 | } 169 | kb_has_prev_report = false; 170 | } 171 | 172 | kb_prev_report = kb_report; 173 | 174 | //------------- Mouse -------------// 175 | if (mouse_report.buttons != mouse_prev_buttons || mouse_report.x != 0 || 176 | mouse_report.y != 0) { 177 | // x,y is only 0, 1, -1 178 | enum { MOUSE_SCALE = 1 }; 179 | mouse_report.x *= MOUSE_SCALE; 180 | mouse_report.y *= MOUSE_SCALE; 181 | 182 | // TODO check for IK_REPORT_MOUSE_DOUBLE_CLICK and 183 | // IK_REPORT_MOUSE_CLICK_HOLD 184 | usb_mouse.sendReport(0, &mouse_report, sizeof(mouse_report)); 185 | color = COLOR_KEY_PRESSED; 186 | } 187 | mouse_prev_buttons = mouse_report.buttons; 188 | 189 | setPixel(color); 190 | } 191 | 192 | void loop() { 193 | static uint32_t ms = 0; 194 | 195 | // scan every 10 ms 196 | if (millis() - ms > SCAN_INTERVAL) { 197 | ms = millis(); 198 | scanMembraneAndSwitch(); 199 | } 200 | 201 | Serial.flush(); 202 | } 203 | 204 | //--------------------------------------------------------------------+ 205 | // Setup and Loop on Core1 206 | //--------------------------------------------------------------------+ 207 | 208 | void setup1() { 209 | IKeys.begin(); 210 | 211 | // while (!Serial) { 212 | // delay(10); // wait for native usb 213 | // } 214 | Serial.println("Core1 setup to run TinyUSB host with pio-usb"); 215 | 216 | // Check for CPU frequency, must be multiple of 120Mhz for bit-banging USB 217 | uint32_t cpu_hz = clock_get_hz(clk_sys); 218 | if (cpu_hz != 120000000UL && cpu_hz != 240000000UL) { 219 | while (!Serial) 220 | delay(10); // wait for native usb 221 | Serial.printf("Error: CPU Clock = %lu, PIO USB require CPU clock must be " 222 | "multiple of 120 Mhz\r\n", 223 | cpu_hz); 224 | Serial.printf("Change your CPU Clock to either 120 or 240 Mhz in Menu->CPU " 225 | "Speed \r\n"); 226 | while (1) { 227 | delay(1); 228 | } 229 | } 230 | 231 | #ifdef PIN_5V_EN 232 | pinMode(PIN_5V_EN, OUTPUT); 233 | digitalWrite(PIN_5V_EN, PIN_5V_EN_STATE); 234 | #endif 235 | 236 | pio_usb_configuration_t pio_cfg = PIO_USB_DEFAULT_CONFIG; 237 | pio_cfg.pin_dp = PIN_USB_HOST_DP; 238 | USBHost.configure_pio_usb(1, &pio_cfg); 239 | 240 | // run host stack on controller (rhport) 1 241 | // Note: For rp2040 pico-pio-usb, calling USBHost.begin() on core1 will have 242 | // most of the host bit-banging processing works done in core1 to free up 243 | // core0 for other works 244 | USBHost.begin(1); 245 | } 246 | 247 | void loop1() { 248 | IKeys.Periodic(); 249 | USBHost.task(); 250 | } 251 | 252 | //--------------------------------------------------------------------+ 253 | // TinyUSB Host callbacks 254 | // Note: running in the same core where Brain.USBHost.task() is called 255 | //--------------------------------------------------------------------+ 256 | extern "C" { 257 | 258 | void tuh_mount_cb(uint8_t daddr) { 259 | Serial.printf("Device attached, address = %d\r\n", daddr); 260 | IKeys.mount(daddr); 261 | } 262 | 263 | /// Invoked when device is unmounted (bus reset/unplugged) 264 | void tuh_umount_cb(uint8_t daddr) { 265 | Serial.printf("Device detached, address = %d\r\n", daddr); 266 | IKeys.umount(daddr); 267 | } 268 | 269 | // Invoked when received report from device via interrupt endpoint 270 | void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t instance, 271 | uint8_t const *report, uint16_t len) { 272 | IKeys.hid_reprot_received_cb(dev_addr, instance, report, len); 273 | } 274 | 275 | } // extern C 276 | 277 | //--------------------------------------------------------------------+ 278 | // Neopixel bit-banging since PIO is used by USBH 279 | //--------------------------------------------------------------------+ 280 | 281 | void __no_inline_not_in_flash_func(setPixel)(uint32_t color) { 282 | static uint32_t end_us = 0; 283 | static uint32_t last_color = 0x123456; 284 | 285 | if (last_color == color) { 286 | // no need to update 287 | return; 288 | } 289 | last_color = color; 290 | 291 | uint8_t r = (uint8_t)(color >> 16); // red 292 | uint8_t g = (uint8_t)(color >> 8); // green 293 | uint8_t b = (uint8_t)color; 294 | 295 | // brightness correction 296 | r = (uint8_t)((r * PIXEL_BRIGHTNESS) >> 8); 297 | g = (uint8_t)((g * PIXEL_BRIGHTNESS) >> 8); 298 | b = (uint8_t)((b * PIXEL_BRIGHTNESS) >> 8); 299 | 300 | uint8_t buf[3] = {g, r, b}; 301 | 302 | uint8_t *ptr, *end, p, bitMask; 303 | 304 | enum { PIN_MASK = (1ul << PIN_NEOPIXEL) }; 305 | 306 | ptr = buf; 307 | end = ptr + 3; 308 | p = *ptr++; 309 | bitMask = 0x80; 310 | 311 | // wait for previous frame to finish 312 | enum { FRAME_TIME_US = 300 }; 313 | 314 | uint32_t now = end_us; 315 | while (now - end_us < FRAME_TIME_US) { 316 | now = micros(); 317 | if (now < end_us) { 318 | // micros() overflow 319 | end_us = now; 320 | } 321 | } 322 | 323 | uint32_t const isr_context = save_and_disable_interrupts(); 324 | 325 | // RP2040 is 120 MHz, 120 cycle = 1us = 1000 ns 326 | // Neopixel is 800 KHz, 1T = 1.25 us = 150 nop 327 | while (1) { 328 | if (p & bitMask) { 329 | // T1H 0,8 us = 96 - 1 = 95 nop 330 | sio_hw->gpio_set = PIN_MASK; 331 | __asm volatile("nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;" 332 | "nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;" 333 | "nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;" 334 | "nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;" 335 | "nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;" 336 | "nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;" 337 | "nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;" 338 | "nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;" 339 | "nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;"); 340 | 341 | // T1L 0,45 = 54 - 10 (ifelse) - 5 (overhead) = 44 nop 342 | sio_hw->gpio_clr = PIN_MASK; 343 | __asm volatile("nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;" 344 | "nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;" 345 | "nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;" 346 | "nop; nop; nop; nop; nop; nop; nop; nop; nop;"); 347 | } else { 348 | // T0H 0,4 us = 48 - 1 = 47 nop 349 | sio_hw->gpio_set = PIN_MASK; 350 | __asm volatile("nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;" 351 | "nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;" 352 | "nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;" 353 | "nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;" 354 | "nop; nop;"); 355 | 356 | // T0L 0.85 us = 102 - 10 (ifelse) - 5 (overhead) = 87 nop 357 | sio_hw->gpio_clr = PIN_MASK; 358 | __asm volatile("nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;" 359 | "nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;" 360 | "nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;" 361 | "nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;" 362 | "nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;" 363 | "nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;" 364 | "nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;" 365 | "nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;" 366 | "nop; nop; nop; nop;"); 367 | } 368 | 369 | if (bitMask >>= 1) { 370 | // not full byte, shift to next bit 371 | __asm volatile("nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;"); 372 | } else { 373 | // probably take 10 nops 374 | // if a full byte is sent, next to another byte 375 | if (ptr >= end) { 376 | break; 377 | } 378 | p = *ptr++; 379 | bitMask = 0x80; 380 | } 381 | } 382 | 383 | restore_interrupts(isr_context); 384 | 385 | end_us = micros(); 386 | } 387 | -------------------------------------------------------------------------------- /intellikeys enumerate-download-reenumerate.tdc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/Adafruit_IntelliKeys/afd23a892c4b3e187de99fdf2c738f058d11ea3b/intellikeys enumerate-download-reenumerate.tdc -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | name=Adafruit IntelliKeys 2 | version=0.2.3 3 | author=Adafruit 4 | maintainer=Adafruit 5 | sentence=IntelliKeys library for Arduino 6 | paragraph=Intellikeys USB Translator 7 | category=Communication 8 | url=https://github.com/adafruit/Adafruit_IntelliKeys 9 | architectures=rp2040 10 | includes=Adafruit_IntelliKeys.h 11 | depends=Adafruit TinyUSB Library, Pico PIO USB, Adafruit SPIFlash, SdFat - Adafruit Fork 12 | -------------------------------------------------------------------------------- /src/Adafruit_IntelliKeys.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2023 Ha Thach (tinyusb.org) for Adafruit Industries 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | #include 26 | 27 | #include "Adafruit_IntelliKeys.h" 28 | #include "intellikeysdefs.h" 29 | 30 | #include "ik_firmware.h" 31 | #include "ik_loader.h" 32 | 33 | //--------------------------------------------------------------------+ 34 | // MACRO TYPEDEF CONSTANT ENUM DECLARATION 35 | //--------------------------------------------------------------------+ 36 | 37 | #define IK_DEBUG 1 38 | #define IK_VID 0x095e 39 | #define IK_PID_FWLOAD 0x0100 // Firmware load required 40 | #define IK_PID_RUNNING 0x0101 // Firmware running 41 | 42 | #if IK_DEBUG 43 | 44 | #define IK_PRINTF(...) Serial.printf(__VA_ARGS__) 45 | 46 | const char *const ik_cmd_str[] = { 47 | [CMD_BASE] = "BASE", 48 | [IK_CMD_GET_VERSION] = "GET_VERSION", 49 | [IK_CMD_LED] = "LED", 50 | [IK_CMD_SCAN] = "SCAN", 51 | [IK_CMD_TONE] = "TONE", 52 | [IK_CMD_GET_EVENT] = "GET_EVENT", 53 | [IK_CMD_INIT] = "INIT", 54 | [IK_CMD_EEPROM_READ] = "EEPROM_READ", 55 | [IK_CMD_EEPROM_WRITE] = "EEPROM_WRITE", 56 | [IK_CMD_ONOFFSWITCH] = "ONOFFSWITCH", 57 | [IK_CMD_CORRECT] = "CORRECT", 58 | [IK_CMD_EEPROM_READBYTE] = "EEPROM_READBYTE", 59 | [IK_CMD_RESET_DEVICE] = "RESET_DEVICE", 60 | [IK_CMD_START_AUTO] = "START_AUTO", 61 | [IK_CMD_STOP_AUTO] = "STOP_AUTO", 62 | [IK_CMD_ALL_LEDS] = "ALL_LEDS", 63 | [IK_CMD_START_OUTPUT] = "START_OUTPUT", 64 | [IK_CMD_STOP_OUTPUT] = "STOP_OUTPUT", 65 | [IK_CMD_ALL_SENSORS] = "ALL_SENSORS", 66 | [CMD_BASE + 19] = "UNKNOWN", 67 | [CMD_BASE + 20] = "UNKNOWN", 68 | [IK_CMD_REFLECT_KEYSTROKE] = "REFLECT_KEYSTROKE", 69 | [IK_CMD_REFLECT_MOUSE_MOVE] = "REFLECT_MOUSE_MOVE", 70 | }; 71 | 72 | const char *const ik_cmd_local_str[]{ 73 | [COMMAND_BASE - COMMAND_BASE] = "BASE", 74 | [IK_CMD_DELAY - COMMAND_BASE] = "IK_CMD_DELAY", 75 | [IK_CMD_MOUSE_MOVE - COMMAND_BASE] = "IK_CMD_MOUSE_MOVE", 76 | [IK_CMD_MOUSE_BUTTON - COMMAND_BASE] = "IK_CMD_MOUSE_BUTTON", 77 | [IK_CMD_KEYBOARD - COMMAND_BASE] = "IK_CMD_KEYBOARD", 78 | [IK_CMD_KEY_DONE - COMMAND_BASE] = "IK_CMD_KEY_DONE", 79 | [IK_CMD_KEY_START - COMMAND_BASE] = "IK_CMD_KEY_START", 80 | [IK_CMD_KEY_REPEAT - COMMAND_BASE] = "IK_CMD_KEY_REPEAT", 81 | [IK_CMD_CP_HELP - COMMAND_BASE] = "IK_CMD_CP_HELP", 82 | [IK_CMD_CP_LIST_FEATURES - COMMAND_BASE] = "IK_CMD_CP_LIST_FEATURES", 83 | [IK_CMD_CP_REFRESH - COMMAND_BASE] = "IK_CMD_CP_REFRESH", 84 | [IK_CMD_CP_TOGGLE - COMMAND_BASE] = "IK_CMD_CP_TOGGLE", 85 | [IK_CMD_KEYBOARD_UNICODE - COMMAND_BASE] = "IK_CMD_KEYBOARD_UNICODE", 86 | [IK_CMD_LIFTALLMODIFIERS - COMMAND_BASE] = "IK_CMD_LIFTALLMODIFIERS", 87 | [IK_CMD_CP_REPORT_REALTIME - COMMAND_BASE] = "IK_CMD_CP_REPORT_REALTIME", 88 | }; 89 | 90 | const char *const ik_event_str[] = { 91 | [EVENT_BASE - EVENT_BASE] = "BASE", 92 | [IK_EVENT_ACK - EVENT_BASE] = "ACK", 93 | [IK_EVENT_MEMBRANE_PRESS - EVENT_BASE] = "MEMBRANE_PRESS", 94 | [IK_EVENT_MEMBRANE_RELEASE - EVENT_BASE] = "MEMBRANE_RELEASE", 95 | [IK_EVENT_SWITCH - EVENT_BASE] = "SWITCH", 96 | [IK_EVENT_SENSOR_CHANGE - EVENT_BASE] = "SENSOR_CHANGE", 97 | [IK_EVENT_VERSION - EVENT_BASE] = "VERSION", 98 | [IK_EVENT_EEPROM_READ - EVENT_BASE] = "EEPROM_READ", 99 | [IK_EVENT_ONOFFSWITCH - EVENT_BASE] = "ONOFFSWITCH", 100 | [IK_EVENT_NOMOREEVENTS - EVENT_BASE] = "NOMOREEVENTS", 101 | [IK_EVENT_MEMBRANE_REPEAT - EVENT_BASE] = "MEMBRANE_REPEAT", 102 | [IK_EVENT_SWITCH_REPEAT - EVENT_BASE] = "SWITCH_REPEAT", 103 | [IK_EVENT_CORRECT_MEMBRANE - EVENT_BASE] = "CORRECT_MEMBRANE", 104 | [IK_EVENT_CORRECT_SWITCH - EVENT_BASE] = "CORRECT_SWITCH", 105 | [IK_EVENT_CORRECT_DONE - EVENT_BASE] = "CORRECT_DONE", 106 | [IK_EVENT_EEPROM_READBYTE - EVENT_BASE] = "EEPROM_READBYTE", 107 | [IK_EVENT_DEVICEREADY - EVENT_BASE] = "DEVICEREADY", 108 | [IK_EVENT_AUTOPILOT_STATE - EVENT_BASE] = "AUTOPILOT_STATE", 109 | [IK_EVENT_DELAY - EVENT_BASE] = "DELAY", 110 | [IK_EVENT_ALL_SENSORS - EVENT_BASE] = "ALL_SENSORS", 111 | }; 112 | 113 | #else 114 | #define IK_PRINTF(...) 115 | #endif 116 | 117 | #if IK_DEBUG >= 2 118 | #define IK_PRINTF2 IK_PRINTF 119 | #else 120 | #define IK_PRINTF2(...) 121 | #endif 122 | 123 | //--------------------------------------------------------------------+ 124 | // Public API 125 | //--------------------------------------------------------------------+ 126 | 127 | Adafruit_IntelliKeys::Adafruit_IntelliKeys(void) 128 | : m_modShift(KEYBOARD_MODIFIER_LEFTSHIFT), 129 | m_modAlt(KEYBOARD_MODIFIER_LEFTALT), 130 | m_modControl(KEYBOARD_MODIFIER_LEFTCTRL), 131 | m_modCommand(KEYBOARD_MODIFIER_LEFTGUI) { 132 | Reset(); 133 | 134 | _membrane_cb = NULL; 135 | _switch_cb = NULL; 136 | _toggle_cb = NULL; 137 | 138 | _custom_overlay = NULL; 139 | _custom_overlay_count = 0; 140 | 141 | tu_fifo_config(&_cmd_ff, _cmd_ff_buf, IK_CMD_FIFO_SIZE, 8, false); 142 | tu_fifo_config_mutex(&_cmd_ff, osal_mutex_create(&_cmd_ff_mutex), NULL); 143 | 144 | // 145 | } 146 | 147 | void Adafruit_IntelliKeys::Reset(void) { 148 | _daddr = 0; 149 | _opened = false; 150 | 151 | m_lastLEDTime = 0; 152 | m_delayUntil = 0; 153 | m_nextCorrect = 0; 154 | 155 | m_newLevel = 0; 156 | m_currentLevel = 0; 157 | 158 | m_lastOverlay = -1; 159 | m_lastOverlayTime = 0; 160 | m_currentOverlay = -1; 161 | 162 | m_toggle = -1; 163 | 164 | memset(m_membrane, 0, sizeof(m_membrane)); 165 | memset(m_last_membrane, 0, sizeof(m_last_membrane)); 166 | memset(m_switches, 0, sizeof(m_switches)); 167 | 168 | m_bEepromValid = false; 169 | 170 | m_firmwareVersionMajor = 0; 171 | m_firmwareVersionMinor = 0; 172 | 173 | m_lastSwitch = 0; 174 | } 175 | 176 | void Adafruit_IntelliKeys::begin(void) { IKOverlay::initStandardOverlays(); } 177 | 178 | bool Adafruit_IntelliKeys::mount(uint8_t daddr) { 179 | uint16_t vid, pid; 180 | tuh_vid_pid_get(daddr, &vid, &pid); 181 | 182 | Serial.printf("VID = %04x, PID = %04x\r\n", vid, pid); 183 | 184 | if (vid != IK_VID) { 185 | return false; 186 | } 187 | 188 | _daddr = daddr; 189 | 190 | if (pid == IK_PID_FWLOAD) { 191 | IK_PRINTF("IK mounted without firmware\n"); 192 | ezusb_StartDevice(); 193 | } else if (pid == IK_PID_RUNNING) { 194 | IK_PRINTF("IK mounted running firmware\n"); 195 | 196 | if (!tuh_hid_receive_report(_daddr, 0)) { 197 | IK_PRINTF("Failed to receive report\n"); 198 | return false; 199 | } 200 | 201 | // Start IK device 202 | Start(); 203 | } else { 204 | return false; 205 | } 206 | 207 | return true; 208 | } 209 | 210 | void Adafruit_IntelliKeys::umount(uint8_t daddr) { 211 | if (daddr == _daddr) { 212 | Reset(); 213 | } 214 | } 215 | 216 | void Adafruit_IntelliKeys::Periodic(void) { 217 | if (!IsOpen()) { 218 | return; // nothing to do 219 | } 220 | 221 | // settle overlay 222 | SettleOverlay(); 223 | 224 | uint32_t now = millis(); 225 | 226 | // setLEDs 227 | if (now > m_lastLEDTime + 100) { 228 | SetLEDs(); 229 | m_lastLEDTime = now; 230 | } 231 | 232 | // request a correction every so often. 233 | if (now > m_nextCorrect) { 234 | DoCorrect(); 235 | m_nextCorrect = now + 500; 236 | } 237 | 238 | // send for not-yet valid eeprom bytes 239 | if (!m_bEepromValid) { 240 | for (uint8_t i = 0; i < sizeof(eeprom_t); i++) { 241 | if (!m_eepromDataValid[i] && m_eepromRequestTime[i] + 500 < now) { 242 | uint8_t report[8] = { 243 | IK_CMD_EEPROM_READBYTE, (uint8_t)(0x80 + i), 0x1F, 0, 0, 0, 0, 0}; 244 | PostCommand(report); 245 | m_eepromRequestTime[i] = now; 246 | } 247 | } 248 | } 249 | 250 | ProcessCommands(); 251 | 252 | // InterpretRaw(); 253 | } 254 | 255 | static bool checkNewKeyboardReport(hid_keyboard_report_t const *report, 256 | ik_report_keyboard_t *ik_keyboard) { 257 | if (ik_keyboard->modifier != 0 && 258 | !(report->modifier & ik_keyboard->modifier)) { 259 | return true; 260 | } 261 | 262 | for (uint8_t i = 0; i < 6; i++) { 263 | if (ik_keyboard->keycode == report->keycode[i]) { 264 | return false; 265 | } 266 | } 267 | 268 | return true; 269 | } 270 | 271 | static void combineMouseReport(hid_mouse_report_t *report, 272 | ik_report_mouse_t *ik_mouse) { 273 | report->buttons |= ik_mouse->buttons; 274 | report->x += ik_mouse->x; 275 | report->y += ik_mouse->y; 276 | } 277 | 278 | void Adafruit_IntelliKeys::getHIDReport(hid_keyboard_report_t *kb_report, 279 | hid_mouse_report_t *mouse_report) { 280 | memset(kb_report, 0, sizeof(hid_keyboard_report_t)); 281 | memset(mouse_report, 0, sizeof(hid_mouse_report_t)); 282 | 283 | if (!IsOpen() || !IsSwitchedOn()) { 284 | return; 285 | } 286 | 287 | IKOverlay *overlay = GetCurrentOverlay(); 288 | if (overlay == NULL) { 289 | return; 290 | } 291 | 292 | uint8_t kb_count = 0; 293 | 294 | //------------- scan membrane -------------// 295 | for (uint8_t i = 0; i < IK_RESOLUTION_X; i++) { 296 | for (uint8_t j = 0; j < IK_RESOLUTION_Y; j++) { 297 | if (m_membrane[i][j] == 1) { 298 | ik_report_t ik_report; 299 | overlay->getMembraneReport(i, j, &ik_report); 300 | 301 | if (ik_report.type == IK_REPORT_TYPE_KEYBOARD) { 302 | // Serial.printf( 303 | // "rol = %u, col = %u, modifier = %02X, keycode = %02X\r\n", i, j, 304 | // ik_report.keyboard.modifier, ik_report.keyboard.keycode); 305 | if (checkNewKeyboardReport(kb_report, &ik_report.keyboard)) { 306 | kb_report->modifier |= ik_report.keyboard.modifier; 307 | if (ik_report.keyboard.keycode != 0) { 308 | kb_report->keycode[kb_count] = ik_report.keyboard.keycode; 309 | kb_count++; 310 | if (kb_count >= 6) { 311 | break; 312 | } 313 | } 314 | } 315 | } else if (ik_report.type == IK_REPORT_TYPE_MOUSE) { 316 | // Serial.printf( 317 | // "rol = %u, col = %u, buttons = %02X, x = %d, y = 318 | // %d\r\n", i, j, ik_report.mouse.buttons, 319 | // ik_report.mouse.x, ik_report.mouse.y); 320 | combineMouseReport(mouse_report, &ik_report.mouse); 321 | } 322 | } 323 | } 324 | } 325 | 326 | // Check for modifier latching 327 | if (m_modShift.GetState() != kModifierStateOff) { 328 | kb_report->modifier |= KEYBOARD_MODIFIER_LEFTSHIFT; 329 | } 330 | 331 | if (m_modAlt.GetState() != kModifierStateOff) { 332 | kb_report->modifier |= KEYBOARD_MODIFIER_LEFTALT; 333 | } 334 | 335 | if (m_modControl.GetState() != kModifierStateOff) { 336 | kb_report->modifier |= KEYBOARD_MODIFIER_LEFTCTRL; 337 | } 338 | 339 | if (m_modCommand.GetState() != kModifierStateOff) { 340 | kb_report->modifier |= KEYBOARD_MODIFIER_LEFTGUI; 341 | } 342 | 343 | if (kb_count) { 344 | PostLiftAllModifiers(); 345 | } 346 | 347 | if (!(mouse_report->buttons & MOUSE_BUTTON_LEFT) && 348 | (m_mouseDown.GetState() != kModifierStateOff)) { 349 | mouse_report->buttons |= MOUSE_BUTTON_LEFT; 350 | } 351 | 352 | // TODO scan switch 353 | } 354 | 355 | void Adafruit_IntelliKeys::InterpretRaw() { 356 | // don't bother if we're not connected and switched on 357 | if (!IsOpen()) { 358 | return; 359 | } 360 | if (!IsSwitchedOn()) { 361 | return; 362 | } 363 | 364 | IKOverlay *overlay = GetCurrentOverlay(); 365 | 366 | // look for _membrane change 367 | for (uint8_t col = 0; col < IK_RESOLUTION_X; col++) { 368 | for (uint8_t row = 0; row < IK_RESOLUTION_Y; row++) { 369 | const uint8_t state = m_membrane[row][col]; 370 | if (state != m_last_membrane[row][col]) { 371 | IK_PRINTF("membrane [%02u, %02u] = %u\r\n", row, col, state); 372 | 373 | if (state) { 374 | ShortKeySound(); 375 | 376 | // Modifier Latching 377 | if (overlay) { 378 | ik_report_t ik_report; 379 | overlay->getMembraneReport(row, col, &ik_report); 380 | 381 | if (ik_report.type == IK_REPORT_TYPE_KEYBOARD) { 382 | uint8_t const modifier = ik_report.keyboard.modifier; 383 | 384 | m_modControl.UpdateState(modifier); 385 | m_modShift.UpdateState(modifier); 386 | m_modAlt.UpdateState(modifier); 387 | m_modCommand.UpdateState(modifier); 388 | } else if (ik_report.type == IK_REPORT_TYPE_MOUSE) { 389 | if (ik_report.mouse.buttons & IK_REPORT_MOUSE_CLICK_HOLD) { 390 | m_mouseDown.ToggleState(); 391 | } 392 | 393 | if (ik_report.mouse.buttons & 394 | (MOUSE_BUTTON_LEFT | IK_REPORT_MOUSE_DOUBLE_CLICK)) { 395 | m_mouseDown.SetState(kModifierStateOff); 396 | } 397 | } 398 | } 399 | } 400 | 401 | // save current state for next time 402 | m_last_membrane[row][col] = state; 403 | 404 | if (_membrane_cb) { 405 | _membrane_cb(row, col, state); 406 | } 407 | } 408 | } 409 | } 410 | 411 | // look for switch change 412 | for (uint8_t nsw = 0; nsw < IK_NUM_SWITCHES; nsw++) { 413 | if (m_switches[nsw] != m_last_switches[nsw]) { 414 | IK_PRINTF("switch %02u = %u\r\n", nsw, m_switches[nsw]); 415 | if (m_switches[nsw]) { 416 | ShortKeySound(); 417 | } 418 | 419 | // save current state for next time 420 | m_last_switches[nsw] = m_switches[nsw]; 421 | 422 | if (_switch_cb) { 423 | _switch_cb(nsw, m_switches[nsw]); 424 | } 425 | } 426 | } 427 | } 428 | 429 | //--------------------------------------------------------------------+ 430 | // Private 431 | //--------------------------------------------------------------------+ 432 | 433 | bool Adafruit_IntelliKeys::Start(void) { 434 | uint8_t command[IK_REPORT_LEN] = {0}; 435 | 436 | command[0] = IK_CMD_INIT; 437 | command[1] = 0; // interrupt event mode 438 | PostCommand(command); 439 | 440 | command[0] = IK_CMD_SCAN; 441 | command[1] = 1; // enable 442 | PostCommand(command); 443 | 444 | PostDelay(250); 445 | 446 | command[0] = IK_CMD_ALL_SENSORS; 447 | command[1] = 0; // unused 448 | PostCommand(command); 449 | 450 | // ask the device for its firmware version 451 | command[0] = IK_CMD_GET_VERSION; 452 | command[1] = 0; // unused 453 | PostCommand(command); 454 | 455 | // reset keyboard 456 | ResetKeyboard(); 457 | 458 | // reset mouse 459 | ResetMouse(); 460 | 461 | _opened = true; 462 | 463 | return false; 464 | } 465 | 466 | bool Adafruit_IntelliKeys::IsNumLockOn(void) { 467 | // implement later 468 | return false; 469 | } 470 | 471 | bool Adafruit_IntelliKeys::IsCapsLockOn(void) { 472 | // implement later 473 | return false; 474 | } 475 | 476 | bool Adafruit_IntelliKeys::IsMouseDown(void) { 477 | return m_mouseDown.GetState() != 0; 478 | } 479 | 480 | void Adafruit_IntelliKeys::DoCorrect(void) { 481 | // clear out data 482 | for (int i = 0; i < IK_NUM_SWITCHES; i++) { 483 | m_switchesPressedInCorrectMode[i] = 0; 484 | } 485 | 486 | for (int x = 0; x < IK_RESOLUTION_X; x++) { 487 | for (int y = 0; y < IK_RESOLUTION_Y; y++) { 488 | m_membranePressedInCorrectMode[y][x] = 0; 489 | } 490 | } 491 | 492 | // send the command 493 | uint8_t report[IK_REPORT_LEN] = {IK_CMD_CORRECT, 0, 0, 0, 0, 0, 0, 0}; 494 | PostCommand(report); 495 | } 496 | 497 | void Adafruit_IntelliKeys::OnCorrectMembrane(int x, int y) { 498 | m_membranePressedInCorrectMode[y][x] = true; 499 | } 500 | 501 | void Adafruit_IntelliKeys::OnCorrectSwitch(int switchnum) { 502 | int ns = switchnum; 503 | m_switchesPressedInCorrectMode[ns - 1] = true; 504 | } 505 | 506 | void Adafruit_IntelliKeys::OnCorrectDone() { 507 | for (int i = 0; i < IK_NUM_SWITCHES; i++) { 508 | m_switches[i] = m_switchesPressedInCorrectMode[i]; 509 | } 510 | 511 | for (int x = 0; x < IK_RESOLUTION_X; x++) { 512 | for (int y = 0; y < IK_RESOLUTION_Y; y++) { 513 | m_membrane[y][x] = m_membranePressedInCorrectMode[y][x]; 514 | } 515 | } 516 | } 517 | 518 | void Adafruit_IntelliKeys::OnMembranePress(int x, int y) { 519 | m_membrane[y][x] = 1; 520 | } 521 | 522 | void Adafruit_IntelliKeys::OnMembraneRelease(int x, int y) { 523 | m_membrane[y][x] = 0; 524 | } 525 | 526 | // All commands processed in this function is sent to device 527 | void Adafruit_IntelliKeys::ProcessCommands() { 528 | uint8_t const idx = 0; 529 | 530 | // come back later if IK_ICMD_DELAY has set a future time 531 | if (millis() < m_delayUntil) { 532 | return; 533 | } 534 | 535 | if (!tuh_hid_send_ready(_daddr, idx)) { 536 | return; 537 | } 538 | 539 | uint8_t command[IK_REPORT_LEN] = {0}; 540 | 541 | if (!tu_fifo_read(&_cmd_ff, command)) { 542 | return; 543 | } 544 | 545 | uint8_t const cmd_id = command[0]; 546 | 547 | if (cmd_id < COMMAND_BASE) { 548 | if (cmd_id > IK_CMD_REFLECT_MOUSE_MOVE) { 549 | IK_PRINTF("ProcessCommand: invalid cmd %d\r\n", cmd_id); 550 | } else { 551 | IK_PRINTF2("ProcessCommand: %s\r\n", ik_cmd_str[cmd_id]); 552 | } 553 | 554 | // blocking until report is sent 555 | while (!tuh_hid_send_report(_daddr, idx, 0, command, IK_REPORT_LEN)) { 556 | tuh_task(); 557 | } 558 | } 559 | } 560 | 561 | bool Adafruit_IntelliKeys::PostCommand(uint8_t *command) { 562 | uint8_t const cmd_id = command[0]; 563 | 564 | if (cmd_id < COMMAND_BASE) { 565 | if (cmd_id > IK_CMD_REFLECT_MOUSE_MOVE) { 566 | IK_PRINTF("PostCommand: invalid cmd %d\r\n", cmd_id); 567 | return false; 568 | } 569 | // IK_PRINTF("PostCommand: %s\r\n", ik_cmd_str[cmd_id]); 570 | 571 | // queue command sent to device 572 | if (!tu_fifo_write(&_cmd_ff, command)) { 573 | IK_PRINTF("PostCommand: Failed to queue command, probably full. Please " 574 | "increase IK_CMD_FIFO_SIZE\n"); 575 | } 576 | } else { 577 | // local driver command 578 | if (cmd_id > IK_CMD_CP_REPORT_REALTIME) { 579 | IK_PRINTF("PostCommand (local): invalid cmd %d\r\n", cmd_id); 580 | return false; 581 | } else { 582 | IK_PRINTF("PostCommand (local): %s\r\n", 583 | ik_cmd_local_str[cmd_id - COMMAND_BASE]); 584 | 585 | switch (cmd_id) { 586 | case IK_CMD_DELAY: 587 | m_delayUntil = millis() + command[1]; 588 | break; 589 | 590 | default: 591 | break; 592 | } 593 | } 594 | } 595 | 596 | return true; 597 | } 598 | 599 | void Adafruit_IntelliKeys::PostSetLED(uint8_t number, uint8_t value) { 600 | uint8_t command[IK_REPORT_LEN] = {IK_CMD_LED, number, value, 0, 0, 0, 0, 0}; 601 | PostCommand(command); 602 | } 603 | 604 | void Adafruit_IntelliKeys::PostDelay(uint8_t msec) { 605 | uint8_t command[IK_REPORT_LEN]; 606 | command[0] = IK_CMD_DELAY; 607 | command[1] = msec; // msec delay 608 | PostCommand(command); 609 | } 610 | 611 | void Adafruit_IntelliKeys::PostKey(int code, int direction, int delayAfter) { 612 | // track shift status and last code up for smart typing. 613 | 614 | if (direction == IK_UP) { 615 | if (code == UNIVERSAL_SHIFT || code == UNIVERSAL_RIGHT_SHIFT) { 616 | m_bShifted = true; 617 | } else { 618 | m_lastCodeUp = code; 619 | m_bShifted = false; 620 | } 621 | } 622 | 623 | uint8_t command[IK_REPORT_LEN]; 624 | command[0] = IK_CMD_KEYBOARD; 625 | command[1] = code; 626 | command[2] = direction; 627 | command[3] = delayAfter & 0xff; 628 | command[4] = (delayAfter / 256) & 0xff; 629 | PostCommand(command); 630 | } 631 | 632 | void Adafruit_IntelliKeys::SetLEDs(void) { 633 | if (!IsSwitchedOn()) { 634 | return; 635 | } 636 | 637 | if (!IsOpen()) { 638 | return; 639 | } 640 | 641 | bool bShift = (m_modShift.GetState() != 0); 642 | bool bControl = (m_modControl.GetState() != 0); 643 | bool bAlt = (m_modAlt.GetState() != 0); 644 | bool bCommand = (m_modCommand.GetState() != 0); 645 | bool bNumLock = IsNumLockOn(); 646 | bool bMouse = IsMouseDown(); 647 | bool bCapsLock = IsCapsLockOn(); 648 | 649 | // 3 lights is shift, caps lock, mouse down 650 | PostSetLED(1, bShift); 651 | PostSetLED(4, bCapsLock); 652 | PostSetLED(7, bMouse); 653 | 654 | // 6 lights is alt, control/command, num lock 655 | bool b6lights = 656 | (IKSettings::GetSettings()->m_iIndicatorLights == kSettings6lights); 657 | if (b6lights) { 658 | PostSetLED(2, bAlt); 659 | PostSetLED(5, bControl || bCommand); 660 | PostSetLED(8, bNumLock); 661 | 662 | PostSetLED(3, false); 663 | PostSetLED(6, false); 664 | PostSetLED(9, false); 665 | } else { 666 | PostSetLED(3, bShift); 667 | PostSetLED(6, bCapsLock); 668 | PostSetLED(9, bMouse); 669 | 670 | PostSetLED(2, false); 671 | PostSetLED(5, false); 672 | PostSetLED(8, false); 673 | } 674 | } 675 | 676 | void Adafruit_IntelliKeys::SweepSound(int iStartFreq, int iEndFreq, 677 | int iDuration) { 678 | uint8_t report[8] = {IK_CMD_TONE, 0, 0, 0, 0, 0, 0, 0}; 679 | 680 | int volume = 2; 681 | 682 | int nLight = 0; 683 | bool bOn = true; 684 | int j = 0; 685 | 686 | int iLoops = iDuration / 5; // 5-msec chunks 687 | for (int i = 0; i < iLoops; i++) { 688 | report[1] = iStartFreq + i * ((iEndFreq - iStartFreq) * 100 / iLoops) / 100; 689 | report[2] = volume; 690 | PostCommand(report); 691 | 692 | j++; 693 | if (j == 5) { 694 | j = 0; 695 | nLight++; 696 | if (nLight > 9) { 697 | bOn = !bOn; 698 | nLight = 1; 699 | } 700 | PostSetLED(nLight, bOn); 701 | } 702 | } 703 | 704 | report[2] = 0; 705 | PostCommand(report); 706 | 707 | // restore lights 708 | for (int i2 = 0; i2 < 9; i2++) { 709 | PostSetLED(i2 + 1, false); 710 | } 711 | } 712 | 713 | void Adafruit_IntelliKeys::PostReportDataToControlPanel(bool bForce) { 714 | #if 0 715 | PostDelay(5); 716 | uint8_t command[IK_REPORT_LEN] = { 717 | IK_CMD_CP_REPORT_REALTIME, bForce, 0, 0, 0, 0, 0, 0}; 718 | PostCommand(command); 719 | #endif 720 | } 721 | 722 | void Adafruit_IntelliKeys::OnToggle(int newValue) { 723 | if (m_toggle != newValue) { 724 | // Reset state (command, input queues) 725 | // PurgeQueues(); 726 | 727 | m_toggle = newValue; 728 | 729 | int freqLow = 200; 730 | int freqHigh = 250; 731 | int duration = 200; 732 | 733 | if (m_toggle == 1) { 734 | SweepSound(freqLow, freqHigh, duration); 735 | } else { 736 | SweepSound(freqHigh, freqLow, duration); 737 | } 738 | 739 | // reset keyboard 740 | ResetKeyboard(); 741 | 742 | // reset mouse 743 | ResetMouse(); 744 | 745 | // IKControlPanel::Refresh(); 746 | 747 | if (_toggle_cb) { 748 | _toggle_cb((uint8_t)m_toggle); 749 | } 750 | } 751 | } 752 | 753 | void Adafruit_IntelliKeys::OnSwitch(int nswitch, int state) { 754 | m_switches[nswitch - 1] = state; 755 | } 756 | 757 | void Adafruit_IntelliKeys::OnSensorChange(int sensor, int value) { 758 | uint32_t now = millis(); 759 | 760 | // save the current sensor value 761 | m_sensors[sensor] = value; 762 | 763 | // what's the new overlay value 764 | int v[IK_NUM_SENSORS]; 765 | 766 | for (int i = 0; i < IK_NUM_SENSORS; i++) { 767 | v[i] = 0; 768 | int midway; 769 | if (m_bEepromValid) { 770 | midway = (50 * m_eepromData.sensorBlack[i] + 771 | 50 * m_eepromData.sensorWhite[i]) / 772 | 100; 773 | } else { 774 | midway = 150; 775 | } 776 | 777 | if (m_sensors[i] > midway) { 778 | v[i] = 1; 779 | } 780 | } 781 | 782 | int newVal = 0; 783 | for (int i = 0; i < IK_NUM_SENSORS; i++) { 784 | newVal += v[i] * (1 << i); 785 | } 786 | 787 | // if the value changed, record what and when 788 | if (newVal != m_lastOverlay) { 789 | m_lastOverlay = newVal; 790 | m_lastOverlayTime = now; 791 | } 792 | } 793 | 794 | void Adafruit_IntelliKeys::ProcessInput(uint8_t const *data, uint8_t len) { 795 | uint8_t const event_id = data[0]; 796 | #if IK_DEBUG 797 | // skip print sensor change since it is a lot 798 | if (event_id != IK_EVENT_SENSOR_CHANGE) { 799 | IK_PRINTF2("Event: %s: ", ik_event_str[event_id - EVENT_BASE]); 800 | for (uint8_t i = 0; i < len; i++) { 801 | IK_PRINTF2("%02x ", data[i]); 802 | } 803 | IK_PRINTF2("\n"); 804 | } 805 | #endif 806 | 807 | switch (event_id) { 808 | case IK_EVENT_MEMBRANE_PRESS: 809 | OnMembranePress(data[1], data[2]); 810 | InterpretRaw(); 811 | PostReportDataToControlPanel(); 812 | break; 813 | 814 | case IK_EVENT_MEMBRANE_RELEASE: 815 | OnMembraneRelease(data[1], data[2]); 816 | InterpretRaw(); 817 | PostReportDataToControlPanel(); 818 | break; 819 | 820 | case IK_EVENT_SWITCH: 821 | OnSwitch(data[1], data[2]); 822 | InterpretRaw(); 823 | PostReportDataToControlPanel(); 824 | break; 825 | 826 | case IK_EVENT_SENSOR_CHANGE: 827 | OnSensorChange(data[1], data[2]); 828 | break; 829 | 830 | case IK_EVENT_VERSION: 831 | // JR - June 2012 - set the firmware version 832 | m_firmwareVersionMajor = data[1]; 833 | m_firmwareVersionMinor = data[2]; 834 | break; 835 | 836 | case IK_EVENT_EEPROM_READ: 837 | break; 838 | 839 | case IK_EVENT_ONOFFSWITCH: 840 | OnToggle(data[1]); 841 | PostReportDataToControlPanel(); 842 | break; 843 | 844 | case IK_EVENT_CORRECT_MEMBRANE: 845 | OnCorrectMembrane(data[1], data[2]); 846 | InterpretRaw(); 847 | PostReportDataToControlPanel(); 848 | break; 849 | 850 | case IK_EVENT_CORRECT_SWITCH: 851 | OnCorrectSwitch(data[1]); 852 | InterpretRaw(); 853 | PostReportDataToControlPanel(); 854 | break; 855 | 856 | case IK_EVENT_CORRECT_DONE: 857 | OnCorrectDone(); 858 | PostReportDataToControlPanel(true); 859 | break; 860 | 861 | case IK_EVENT_EEPROM_READBYTE: 862 | StoreEEProm(data[1], data[2], data[3]); 863 | break; 864 | 865 | case IK_EVENT_AUTOPILOT_STATE: 866 | break; 867 | 868 | default: 869 | break; 870 | 871 | // We should not see these. 872 | 873 | case IK_EVENT_ACK: 874 | case IK_EVENT_DEVICEREADY: 875 | case IK_EVENT_NOMOREEVENTS: 876 | case IK_EVENT_MEMBRANE_REPEAT: 877 | case IK_EVENT_SWITCH_REPEAT: 878 | // error?? 879 | break; 880 | } 881 | } 882 | 883 | void Adafruit_IntelliKeys::PostLiftAllModifiers() { 884 | // run IK_CMD_LIFTALLMODIFIERS right here instead of using PostCommand 885 | m_modShift.SetState(kModifierStateOff); 886 | m_modAlt.SetState(kModifierStateOff); 887 | m_modControl.SetState(kModifierStateOff); 888 | m_modCommand.SetState(kModifierStateOff); 889 | } 890 | 891 | void Adafruit_IntelliKeys::PostCPRefresh() { 892 | uint8_t command[IK_REPORT_LEN] = {IK_CMD_CP_REFRESH, 0, 0, 0, 0, 0, 0, 0}; 893 | PostCommand(command); 894 | } 895 | 896 | void Adafruit_IntelliKeys::ResetKeyboard(void) { 897 | // reset keyboard 898 | // reconcile with modifier objects? 899 | PostLiftAllModifiers(); 900 | } 901 | 902 | void Adafruit_IntelliKeys::ResetMouse(void) { 903 | // reset mouse 904 | m_mouseDown.SetState(kModifierStateOff); 905 | } 906 | 907 | void Adafruit_IntelliKeys::OnStdOverlayChange() { 908 | ResetKeyboard(); 909 | ResetMouse(); 910 | PostLiftAllModifiers(); 911 | // SetLevel(1); 912 | 913 | #if 0 914 | if (DATAI(TEXT("Reload_Standard_Overlay_When_Recognized"),0)==1) 915 | { 916 | IKEngine::GetEngine()->LoadStandardOverlays(); 917 | } 918 | #endif 919 | 920 | LongKeySound(); 921 | OverlayRecognitionFeedback(); 922 | 923 | // tell the CP 924 | PostCPRefresh(); 925 | 926 | // tell raw mode 927 | #if 0 928 | bool bRaw = IKEngine::GetEngine()->GetRawMode(); 929 | if (bRaw) { 930 | uint32_t time = millis(); 931 | queueEntry qe; 932 | qe.buffer[0] = 3; // event type 933 | 934 | if (m_currentOverlay == 7) { 935 | qe.buffer[1] = 0; // overlay number 936 | } 937 | else { 938 | qe.buffer[1] = m_currentOverlay + 1; // overlay number 939 | } 940 | 941 | qe.buffer[2] = 0; // unused 942 | qe.buffer[3] = 0; // unused 943 | *((unsigned int *)&(qe.buffer[4])) = time; 944 | m_rawQueue.enqueue(qe); 945 | } 946 | #endif 947 | } 948 | 949 | bool Adafruit_IntelliKeys::HasStandardOverlay() { 950 | // 0-6 is standard overlay, 7 is no overlay 951 | return (0 <= m_currentOverlay && m_currentOverlay < 7); 952 | } 953 | 954 | IKOverlay *Adafruit_IntelliKeys::GetCurrentOverlay() { 955 | if (HasStandardOverlay()) { 956 | return &stdOverlays[m_currentOverlay]; 957 | } else if ((m_currentOverlay > 7) && 958 | (m_currentOverlay - 8 < _custom_overlay_count) && 959 | (_custom_overlay != NULL)) { 960 | return &_custom_overlay[m_currentOverlay - 8]; 961 | } else { 962 | return NULL; 963 | } 964 | } 965 | 966 | void Adafruit_IntelliKeys::OverlayRecognitionFeedback() { 967 | // PostMonitorState(false); 968 | 969 | int delay = 300; 970 | 971 | if (IsSwitchedOn()) { 972 | PostSetLED(1, true); 973 | PostSetLED(4, true); 974 | PostSetLED(7, true); 975 | PostDelay(delay); 976 | PostSetLED(1, false); 977 | PostSetLED(4, false); 978 | PostSetLED(7, false); 979 | 980 | PostSetLED(2, true); 981 | PostSetLED(5, true); 982 | PostSetLED(8, true); 983 | PostDelay(delay); 984 | PostSetLED(2, false); 985 | PostSetLED(5, false); 986 | PostSetLED(8, false); 987 | 988 | PostSetLED(3, true); 989 | PostSetLED(6, true); 990 | PostSetLED(9, true); 991 | PostDelay(delay); 992 | PostSetLED(3, false); 993 | PostSetLED(6, false); 994 | PostSetLED(9, false); 995 | } else { 996 | for (int numFlashes = 0; numFlashes < 6; numFlashes++) { 997 | PostSetLED(2, true); 998 | PostSetLED(5, true); 999 | PostSetLED(8, true); 1000 | PostDelay(delay); 1001 | // PostLedReconcile(); 1002 | 1003 | PostDelay(delay); 1004 | 1005 | PostSetLED(2, false); 1006 | PostSetLED(5, false); 1007 | PostSetLED(8, false); 1008 | PostDelay(delay); 1009 | // PostLedReconcile(); 1010 | 1011 | PostDelay(delay); 1012 | } 1013 | } 1014 | 1015 | // PostMonitorState(true); 1016 | 1017 | // PostLedReconcile(); 1018 | } 1019 | 1020 | int Adafruit_IntelliKeys::GetLevel() { return m_currentLevel; } 1021 | 1022 | void Adafruit_IntelliKeys::SetLevel(int level) { m_currentLevel = level; } 1023 | 1024 | void Adafruit_IntelliKeys::SettleOverlay() { 1025 | uint32_t now = millis(); 1026 | 1027 | // settle overlay 1028 | if (m_lastOverlay != m_currentOverlay && now > m_lastOverlayTime + 1000) { 1029 | m_currentOverlay = m_lastOverlay; 1030 | IK_PRINTF("Settled on overlay %d\n", m_currentOverlay); 1031 | 1032 | SetLevel(1); 1033 | 1034 | OnStdOverlayChange(); 1035 | } 1036 | } 1037 | 1038 | void Adafruit_IntelliKeys::ShortKeySound() { KeySound(50); } 1039 | 1040 | void Adafruit_IntelliKeys::LongKeySound() { KeySound(700); } 1041 | 1042 | void Adafruit_IntelliKeys::KeySound(int msLength) { 1043 | KeySoundVol(msLength, IKSettings::GetSettings()->m_iKeySoundVolume); 1044 | } 1045 | 1046 | void Adafruit_IntelliKeys::KeySoundVol(int msLength, int vol) { 1047 | int myVol = vol; 1048 | if (vol == -1) { 1049 | myVol = IKSettings::GetSettings()->m_iKeySoundVolume; 1050 | } 1051 | 1052 | // set parameters and blow 1053 | uint8_t report[IK_REPORT_LEN] = {IK_CMD_TONE, 0, 0, 0, 0, 0, 0, 0}; 1054 | report[1] = 247; 1055 | report[2] = myVol; 1056 | report[3] = msLength / 10; 1057 | PostCommand(report); 1058 | } 1059 | 1060 | void Adafruit_IntelliKeys::StoreEEProm(uint8_t data, uint8_t add_lsb, 1061 | uint8_t add_msb) { 1062 | // store the uint8_t received; 1063 | int ndx = add_lsb - 0x80; 1064 | 1065 | uint8_t *e = (uint8_t *)&m_eepromData; 1066 | e[ndx] = data; 1067 | 1068 | // mark the uint8_t valid; 1069 | m_eepromDataValid[ndx] = true; 1070 | 1071 | // check to see if all the uint8_ts are valid. 1072 | // if so, say we're valid and refresh the 1073 | // control panel. 1074 | int nInvalid = 0; 1075 | for (unsigned int i = 0; i < sizeof(eeprom_t); i++) { 1076 | if (!m_eepromDataValid[i]) { 1077 | nInvalid++; 1078 | } 1079 | } 1080 | 1081 | if (nInvalid == 0 && !m_bEepromValid) { 1082 | if (m_eepromData.serialnumber[0] == 'C' && 1083 | m_eepromData.serialnumber[1] == '-') { 1084 | m_bEepromValid = true; 1085 | IK_PRINTF("EEPROM data valid\n"); 1086 | PostCPRefresh(); 1087 | } 1088 | } 1089 | } 1090 | 1091 | void Adafruit_IntelliKeys::hid_reprot_received_cb(uint8_t daddr, uint8_t idx, 1092 | uint8_t const *report, 1093 | uint16_t len) { 1094 | // IDX 0 is HID Generic 1095 | if (idx != 0) { 1096 | return; 1097 | } 1098 | 1099 | if (len != IK_REPORT_LEN) { 1100 | IK_PRINTF("Invalid report length %d\n", len); 1101 | return; 1102 | } 1103 | 1104 | ProcessInput(report, len); 1105 | 1106 | if (!tuh_hid_receive_report(daddr, idx)) { 1107 | IK_PRINTF("Failed to receive report\n"); 1108 | return; 1109 | } 1110 | } 1111 | 1112 | //--------------------------------------------------------------------+ 1113 | // EZUSB 1114 | //--------------------------------------------------------------------+ 1115 | 1116 | // Make an firmware load control request 1117 | bool Adafruit_IntelliKeys::ezusb_load_xfer(uint8_t bRequest, uint16_t addr, 1118 | const void *buffer, uint16_t len) { 1119 | tusb_control_request_t const request = { 1120 | .bmRequestType_bit = {.recipient = TUSB_REQ_RCPT_DEVICE, 1121 | .type = TUSB_REQ_TYPE_VENDOR, 1122 | .direction = TUSB_DIR_OUT}, 1123 | .bRequest = bRequest, 1124 | .wValue = tu_htole16(addr), 1125 | .wIndex = 0, 1126 | .wLength = tu_htole16(len), 1127 | }; 1128 | 1129 | tuh_xfer_t xfer = {.daddr = _daddr, 1130 | .ep_addr = 0, 1131 | .setup = &request, 1132 | .buffer = (uint8_t *)buffer, 1133 | .complete_cb = NULL, 1134 | .user_data = 0}; 1135 | 1136 | if (!tuh_control_xfer(&xfer)) { 1137 | return false; 1138 | } 1139 | 1140 | return xfer.result == XFER_RESULT_SUCCESS; 1141 | } 1142 | 1143 | bool Adafruit_IntelliKeys::ezusb_StartDevice(void) { 1144 | IK_PRINTF("Downloading firmware\n"); 1145 | 1146 | xfer_result_t result = XFER_RESULT_INVALID; 1147 | tuh_interface_set(_daddr, 0, 0, NULL, (uintptr_t)&result); 1148 | 1149 | if (result != XFER_RESULT_SUCCESS) { 1150 | IK_PRINTF("Failed to Set Interface\n"); 1151 | return false; 1152 | } 1153 | 1154 | // First download loader firmware. The loader firmware implements a vendor 1155 | // specific command that will allow us to anchor load to external ram 1156 | ezusb_8051Reset(1); 1157 | ezusb_DownloadIntelHex(ik_loader); 1158 | ezusb_8051Reset(0); 1159 | 1160 | // Now download the device firmware 1161 | ezusb_DownloadIntelHex(ik_firmware); 1162 | ezusb_8051Reset(1); 1163 | ezusb_8051Reset(0); 1164 | 1165 | IK_PRINTF("Downloaded firmware\n"); 1166 | 1167 | return true; 1168 | } 1169 | 1170 | bool Adafruit_IntelliKeys::ezusb_DownloadIntelHex( 1171 | INTEL_HEX_RECORD const *hex_record) { 1172 | // The download must be performed in two passes. The first pass loads all of 1173 | // the external addresses, and the 2nd pass loads to all of the internal 1174 | // addresses. why? because downloading to the internal addresses will 1175 | // probably wipe out the firmware running on the device that knows how to 1176 | // receive external ram downloads. 1177 | 1178 | // First download all the records that go in external ram 1179 | ezusb_downloadHex(hex_record, false); 1180 | 1181 | // Now download all of the records that are in internal RAM. Before starting 1182 | // the download, stop the 8051. 1183 | ezusb_8051Reset(1); 1184 | 1185 | ezusb_downloadHex(hex_record, true); 1186 | 1187 | return false; 1188 | } 1189 | 1190 | bool Adafruit_IntelliKeys::ezusb_downloadHex(INTEL_HEX_RECORD const *ptr, 1191 | bool internal_ram) { 1192 | // First download all the records that go in external ram 1193 | while (ptr->Type == 0) { 1194 | if (INTERNAL_RAM(ptr->Address) == internal_ram) { 1195 | // IK_PRINTF("Downloading %d uint8_ts to 0x%x\n", ptr->Length, 1196 | // ptr->Address); 1197 | 1198 | uint8_t const bRequest = 1199 | internal_ram ? ANCHOR_LOAD_INTERNAL : ANCHOR_LOAD_EXTERNAL; 1200 | if (!ezusb_load_xfer(bRequest, ptr->Address, ptr->Data, ptr->Length)) { 1201 | IK_PRINTF("Failed to load hex file"); 1202 | return false; 1203 | } 1204 | } 1205 | 1206 | ptr++; 1207 | } 1208 | 1209 | return true; 1210 | } 1211 | 1212 | bool Adafruit_IntelliKeys::ezusb_8051Reset(uint8_t resetBit) { 1213 | return ezusb_load_xfer(ANCHOR_LOAD_INTERNAL, CPUCS_REG, &resetBit, 1); 1214 | } 1215 | -------------------------------------------------------------------------------- /src/Adafruit_IntelliKeys.h: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2023 Ha Thach (tinyusb.org) for Adafruit Industries 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | #ifndef ADAFRUIT_INTELLIKEYS_H_ 26 | #define ADAFRUIT_INTELLIKEYS_H_ 27 | 28 | #include "Adafruit_TinyUSB.h" 29 | #include "intellikeysdefs.h" 30 | 31 | #include "IKModifier.h" 32 | #include "IKOverlay.h" 33 | #include "IKUniversal.h" 34 | 35 | // maximum numbers 36 | #define MAX_INTELLIKEYS 10 37 | #define MAX_STANDARD_OVERLAYS 8 38 | #define MAX_SWITCH_OVERLAYS 30 39 | 40 | #define IK_CMD_FIFO_SIZE 128 41 | 42 | class Adafruit_IntelliKeys { 43 | public: 44 | typedef void (*membrane_callback_t)(uint8_t row, uint8_t col, uint8_t state); 45 | typedef void (*switch_callback_t)(uint8_t sw, uint8_t state); 46 | typedef void (*toggle_callback_t)(uint8_t state); 47 | 48 | Adafruit_IntelliKeys(void); 49 | 50 | //--------------------------------------------------------------------+ 51 | // Arduino API 52 | //--------------------------------------------------------------------+ 53 | 54 | void begin(void); 55 | bool mount(uint8_t daddr); 56 | void umount(uint8_t daddr); 57 | 58 | void setCustomOverlay(IKOverlay *overlay, uint32_t count) { 59 | _custom_overlay = overlay; 60 | _custom_overlay_count = count; 61 | } 62 | 63 | void getHIDReport(hid_keyboard_report_t *kb_report, 64 | hid_mouse_report_t *mouse_report); 65 | void Periodic(void); 66 | 67 | void onMemBraneChanged(membrane_callback_t func) { _membrane_cb = func; } 68 | void onSwitchChanged(switch_callback_t func) { _switch_cb = func; } 69 | void onToggleChanged(toggle_callback_t func) { _toggle_cb = func; } 70 | 71 | uint8_t const (*getMembrane(void))[IK_RESOLUTION_Y] { return m_membrane; } 72 | 73 | //--------------------------------------------------------------------+ 74 | // Function named following IKDevice in OpenIKeys 75 | //--------------------------------------------------------------------+ 76 | 77 | bool isAttached(void) { return _daddr != 0; } 78 | bool IsOpen(void) { return _opened; } 79 | bool IsSwitchedOn(void) { return m_toggle == 1; } 80 | bool IsNumLockOn(void); 81 | bool IsCapsLockOn(void); 82 | bool IsMouseDown(void); 83 | 84 | bool PostCommand(uint8_t *command); 85 | void PostDelay(uint8_t msec); 86 | void PostSetLED(uint8_t number, uint8_t value); 87 | void PostKey(int code, int direction, int delayAfter = 0); 88 | void PostLiftAllModifiers(void); 89 | void PostCPRefresh(); 90 | void PostReportDataToControlPanel(bool bForce = false); 91 | void ProcessCommands(); 92 | 93 | void OnToggle(int newValue); 94 | void OnSwitch(int nswitch, int state); 95 | void OnSensorChange(int sensor, int value); 96 | void StoreEEProm(uint8_t data, uint8_t add_lsb, uint8_t add_msb); 97 | void ProcessInput(uint8_t const *data, uint8_t len); 98 | 99 | void SetLEDs(void); 100 | void SweepSound(int iStartFreq, int iEndFreq, int iDuration); 101 | 102 | void OnMembranePress(int x, int y); 103 | void OnMembraneRelease(int x, int y); 104 | void OnCorrectSwitch(int switchnum); 105 | void DoCorrect(); 106 | void OnCorrectMembrane(int x, int y); 107 | void OnCorrectDone(); 108 | 109 | void ResetKeyboard(void); 110 | void ResetMouse(void); 111 | 112 | int GetLevel(); 113 | void SetLevel(int level); 114 | int GetCurrentOverlayNumber() { return m_currentOverlay; } 115 | bool HasStandardOverlay(); 116 | IKOverlay *GetCurrentOverlay(); 117 | void SettleOverlay(); 118 | void OnStdOverlayChange(); 119 | void OverlayRecognitionFeedback(); 120 | int GetDevType() { return 1; /* 1 is IntelliKeys */ } 121 | 122 | void ShortKeySound(); 123 | void LongKeySound(); 124 | void KeySound(int msLength); 125 | void KeySoundVol(int msLength, int volume = -1); 126 | void InterpretRaw(); 127 | 128 | void hid_reprot_received_cb(uint8_t dev_addr, uint8_t instance, 129 | uint8_t const *report, uint16_t len); 130 | 131 | private: 132 | uint8_t _daddr; 133 | uint8_t _opened; 134 | 135 | membrane_callback_t _membrane_cb; 136 | switch_callback_t _switch_cb; 137 | toggle_callback_t _toggle_cb; 138 | 139 | IKOverlay *_custom_overlay; 140 | uint32_t _custom_overlay_count; 141 | 142 | //------------- From OpenIKeys -------------// 143 | 144 | int m_currentLevel; 145 | int m_newLevel; 146 | 147 | uint32_t m_lastLEDTime; 148 | uint32_t m_delayUntil; 149 | uint32_t m_nextCorrect; 150 | 151 | int m_toggle; // on/off switch 152 | int m_sensors[IK_NUM_SENSORS]; 153 | 154 | int m_lastSwitch; 155 | 156 | // overlay recognition 157 | int m_lastOverlay; 158 | uint32_t m_lastOverlayTime; 159 | int m_currentOverlay; 160 | 161 | // reading the eeprom 162 | eeprom_t m_eepromData; 163 | unsigned int m_eepromRequestTime[sizeof(eeprom_t)]; 164 | bool m_eepromDataValid[sizeof(eeprom_t)]; 165 | bool m_bEepromValid; 166 | 167 | // for correction 168 | uint8_t m_membranePressedInCorrectMode[IK_RESOLUTION_X][IK_RESOLUTION_Y]; 169 | uint8_t m_switchesPressedInCorrectMode[IK_NUM_SWITCHES]; 170 | 171 | uint8_t m_last_membrane[IK_RESOLUTION_X][IK_RESOLUTION_Y]; 172 | uint8_t m_last_switches[IK_NUM_SWITCHES]; 173 | 174 | uint8_t m_membrane[IK_RESOLUTION_X][IK_RESOLUTION_Y]; 175 | uint8_t m_switches[IK_NUM_SWITCHES]; 176 | 177 | uint8_t m_firmwareVersionMajor; 178 | uint8_t m_firmwareVersionMinor; 179 | 180 | int m_lastCodeUp; 181 | bool m_bShifted; 182 | 183 | IKModifier m_modShift; 184 | IKModifier m_modAlt; 185 | IKModifier m_modControl; 186 | IKModifier m_modCommand; 187 | 188 | IKModifier m_mouseDown; 189 | 190 | tu_fifo_t _cmd_ff; 191 | OSAL_MUTEX_DEF(_cmd_ff_mutex); 192 | uint8_t _cmd_ff_buf[8 * IK_CMD_FIFO_SIZE]; 193 | 194 | bool Start(void); 195 | void Reset(void); 196 | 197 | // ezusb 198 | bool ezusb_StartDevice(void); 199 | bool ezusb_DownloadIntelHex(INTEL_HEX_RECORD const *record); 200 | bool ezusb_8051Reset(uint8_t resetBit); 201 | 202 | // internal helper 203 | bool ezusb_load_xfer(uint8_t brequest, uint16_t addr, const void *buffer, 204 | uint16_t len); 205 | bool ezusb_downloadHex(INTEL_HEX_RECORD const *record, bool internal_ram); 206 | }; 207 | 208 | #endif 209 | -------------------------------------------------------------------------------- /src/IKModifier.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2023 Ha Thach (thach@tinyusb.org) for Adafruit Industries 5 | */ 6 | 7 | #include "Arduino.h" 8 | 9 | #include "Adafruit_IntelliKeys.h" 10 | #include "IKModifier.h" 11 | 12 | #define IK_MODIFIER_CHANGE_DELAY 5 13 | 14 | void IKModifier::ToggleState() { 15 | // skip if it is changed in the last 5ms 16 | if (millis() - m_lastTime > IK_MODIFIER_CHANGE_DELAY) { 17 | m_lastTime = millis(); 18 | m_state = (m_state == kModifierStateOff) ? kModifierStateLatched 19 | : kModifierStateOff; 20 | } 21 | } 22 | 23 | void IKModifier::UpdateState(uint8_t mask) { 24 | // skip if it is changed in the last 5ms 25 | if (millis() - m_lastTime > IK_MODIFIER_CHANGE_DELAY) { 26 | m_lastTime = millis(); 27 | 28 | if (mask & m_mask) { 29 | // toggle if it is our mask 30 | m_state = (m_state == kModifierStateOff) ? kModifierStateLatched 31 | : kModifierStateOff; 32 | } 33 | } 34 | } 35 | 36 | void IKModifier::SetState(int state) { m_state = state; } 37 | 38 | void IKModifier::Execute(int code) { 39 | int theCode = m_universalCode; 40 | m_universalCodeOverride = 0; 41 | if (code != 0) { 42 | theCode = code; 43 | m_universalCodeOverride = theCode; 44 | } 45 | 46 | IKSettings *pSettings = IKSettings::GetSettings(); 47 | if (pSettings == NULL) 48 | return; 49 | 50 | switch (pSettings->m_iShiftKeyAction) { 51 | case kSettingsShiftLatching: 52 | if (m_state == kModifierStateOff) { 53 | // was off, turn on and put down 54 | m_device->PostKey(theCode, IK_DOWN); 55 | m_state = kModifierStateLatched; 56 | } else { 57 | // was on, put up and turn off 58 | m_device->PostKey(theCode, IK_UP); 59 | m_state = kModifierStateOff; 60 | } 61 | break; 62 | 63 | case kSettingsShiftLocking: 64 | if (m_state == kModifierStateOff) { 65 | // put key down, state = latched 66 | m_device->PostKey(theCode, IK_DOWN); 67 | m_state = kModifierStateLatched; 68 | } else if (m_state == kModifierStateLatched) { 69 | // leave key alone, state = locked 70 | m_state = kModifierStateLocked; 71 | } else if (m_state == kModifierStateLocked) { 72 | // put key up, state = off 73 | m_device->PostKey(theCode, IK_UP); 74 | m_state = kModifierStateOff; 75 | } 76 | break; 77 | 78 | case kSettingsShiftNoLatch: 79 | // just put the key down/up, no change in state 80 | { 81 | int keyDownDelay = 5; 82 | m_device->PostKey(theCode, IK_DOWN, keyDownDelay); 83 | // m_device->PostKey(theCode,IK_UP,keyDownDelay); 84 | m_state = kModifierStateLatched; 85 | } 86 | break; 87 | 88 | default: 89 | break; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/IKModifier.h: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2023 Ha Thach (thach@tinyusb.org) for Adafruit Industries 5 | */ 6 | 7 | #ifndef ADAFRUIT_INTELLIKEYS_IKMODIFIER_H 8 | #define ADAFRUIT_INTELLIKEYS_IKMODIFIER_H 9 | 10 | #include "IKSettings.h" 11 | #include 12 | #include 13 | 14 | // for keystrokes and mouse buttons 15 | enum { IK_DOWN = 1, IK_UP, IK_TOGGLE }; 16 | enum { 17 | IKUSB_LEFT_BUTTON = 0, 18 | IKUSB_RIGHT_BUTTON, 19 | IKUSB_MIDDLE_BUTTON, 20 | IKUSB_BUTTON_4, 21 | IKUSB_BUTTON_5, 22 | IKUSB_BUTTON_6, 23 | IKUSB_BUTTON_7, 24 | IKUSB_BUTTON_8 25 | }; 26 | 27 | enum { kModifierStateOff = 0, kModifierStateLatched, kModifierStateLocked }; 28 | 29 | class Adafruit_IntelliKeys; 30 | 31 | class IKModifier { 32 | 33 | public: 34 | IKModifier(uint8_t mask = 0) { 35 | m_state = kModifierStateOff; 36 | m_lastTime = 0; 37 | m_mask = mask; 38 | } 39 | virtual ~IKModifier() {} 40 | void Execute(int code = 0); 41 | uint8_t GetState() { return m_state; } 42 | void SetState(int state); 43 | void SetCode(uint8_t code) { m_universalCode = code; } 44 | 45 | void ToggleState(); 46 | void UpdateState(uint8_t mask); 47 | 48 | uint8_t m_state; 49 | uint8_t m_mask; 50 | 51 | int m_universalCode; 52 | int m_universalCodeOverride; 53 | uint32_t m_lastTime; 54 | 55 | void SetDevice(Adafruit_IntelliKeys *pDev) { m_device = pDev; } 56 | Adafruit_IntelliKeys *m_device; 57 | }; 58 | 59 | #endif // ADAFRUIT_INTELLIKEYS_IKMODIFIER_H 60 | -------------------------------------------------------------------------------- /src/IKOverlay.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2023 Ha Thach (thach@tinyusb.org) for Adafruit Industries 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | #include "IKOverlay.h" 26 | #include "class/hid/hid.h" 27 | 28 | #define IK_DEBUG 0 29 | 30 | #if IK_DEBUG 31 | #include 32 | #define IK_PRINTF(...) serial1_printf(__VA_ARGS__) 33 | #else 34 | #define IK_PRINTF(...) 35 | #endif 36 | 37 | IKOverlay stdOverlays[7]; 38 | 39 | IKOverlay::IKOverlay() { memset(_membrane, 0, sizeof(_membrane)); } 40 | 41 | void IKOverlay::getSwitchReport(int nswitch, ik_report_t *report) { 42 | (void)nswitch; 43 | (void)report; 44 | } 45 | 46 | void IKOverlay::getMembraneReport(int row, int col, ik_report_t *report) { 47 | if (row > IK_RESOLUTION_X || col > IK_RESOLUTION_Y) { 48 | return; 49 | } 50 | *report = _membrane[row][col]; 51 | } 52 | 53 | void IKOverlay::setMembraneReport(int top_row, int top_col, int height, 54 | int width, ik_report_t *report) { 55 | if (!(top_row < IK_RESOLUTION_X && top_col < IK_RESOLUTION_Y)) { 56 | IK_PRINTF("Invalid top row or top col [%u, %u]\r\n", top_row, top_col); 57 | return; 58 | } 59 | 60 | if (!((top_row + height <= IK_RESOLUTION_X) && 61 | (top_col + width <= IK_RESOLUTION_Y))) { 62 | IK_PRINTF("Invalid height or width [%u, %u] + [%u, %u] = [%u, %u]\r\n", 63 | top_row, top_col, height, width, top_row + height, 64 | top_col + width); 65 | return; 66 | } 67 | 68 | for (int row = top_row; row < top_row + height; row++) { 69 | for (int col = top_col; col < top_col + width; col++) { 70 | _membrane[row][col] = *report; 71 | } 72 | } 73 | } 74 | 75 | void IKOverlay::initStandardOverlays(void) { 76 | initStdWebAccess(); 77 | initStdMathAccess(); 78 | initStdAlphabet(); 79 | initStdMouseAccess(); 80 | initStdQwerty(); 81 | initStdBasicWriting(); 82 | } 83 | 84 | //--------------------------------------------------------------------+ 85 | // Web Access 86 | //--------------------------------------------------------------------+ 87 | void IKOverlay::initStdWebAccess(void) { 88 | IKOverlay &overlay = stdOverlays[IK_OVERLAY_WEB_ACCESS]; 89 | 90 | int row, col; 91 | int const height = 3; 92 | int const width = 2; 93 | 94 | //------------- first row -------------// 95 | row = 0; 96 | col = 0; 97 | 98 | ik_report_keyboard_t const first_row[] = { 99 | {KEYBOARD_MODIFIER_LEFTALT, HID_KEY_ARROW_LEFT}, // backward in browser 100 | {KEYBOARD_MODIFIER_LEFTALT, HID_KEY_ARROW_RIGHT}, // forward in browser 101 | {0, HID_KEY_ESCAPE}, // stop 102 | {0, HID_KEY_F5}, // refresh 103 | {KEYBOARD_MODIFIER_LEFTALT, HID_KEY_HOME}, // open home page 104 | {0, HID_KEY_F3}, // search 105 | {0, 0}, // TODO bookmark ? 106 | {KEYBOARD_MODIFIER_LEFTCTRL, HID_KEY_H}, // History with Ctrl+H 107 | {KEYBOARD_MODIFIER_LEFTCTRL, HID_KEY_P}, // Print with Ctrl+P 108 | {KEYBOARD_MODIFIER_LEFTCTRL, HID_KEY_C}, // Copy with Ctrl+C 109 | {0, 0}, // TODO Internet Explorer: Launch default browser ? 110 | {0, 0}, // TODO Netscape ?? 111 | }; 112 | 113 | overlay.setMembraneKeyboardArr(row, col, height, width, first_row, 114 | sizeof(first_row) / sizeof(first_row[0])); 115 | 116 | //------------- second row -------------// 117 | row = 3; 118 | col = 0; 119 | 120 | ik_report_keyboard_t const second_row[] = { 121 | {0, HID_KEY_TAB}, 122 | {0, HID_KEY_SLASH}, 123 | {0, HID_KEY_GRAVE}, 124 | {0, 0}, // empty 125 | {KEYBOARD_MODIFIER_LEFTCTRL, HID_KEY_L}, // goto address bar 126 | // www. 127 | // .com 128 | // .net 129 | // .gov 130 | // .edu 131 | // .org 132 | // IntelliTools ? 133 | }; 134 | 135 | overlay.setMembraneKeyboardArr(row, col, height, width, second_row, 136 | sizeof(second_row) / sizeof(second_row[0])); 137 | 138 | // Row 3 to 8 139 | initStdQwertyRow3to8(overlay, true); 140 | } 141 | 142 | //--------------------------------------------------------------------+ 143 | // Math Access 144 | //--------------------------------------------------------------------+ 145 | void IKOverlay::initStdMathAccess(void) { 146 | IKOverlay &overlay = stdOverlays[IK_OVERLAY_MATH_ACCESS]; 147 | 148 | ik_report_t kb_report = {.type = IK_REPORT_TYPE_KEYBOARD, .keyboard = {0, 0}}; 149 | ik_report_t mouse_report = {.type = IK_REPORT_TYPE_MOUSE, .mouse = {0, 0, 0}}; 150 | 151 | int row, col, height, width; 152 | 153 | //------------- Calculator -------------// 154 | height = 6; 155 | width = 4; 156 | 157 | uint8_t const numbpad[] = { 158 | HID_KEY_KEYPAD_7, HID_KEY_KEYPAD_8, HID_KEY_KEYPAD_9, 159 | HID_KEY_KEYPAD_4, HID_KEY_KEYPAD_5, HID_KEY_KEYPAD_6, 160 | HID_KEY_KEYPAD_1, HID_KEY_KEYPAD_2, HID_KEY_KEYPAD_3, 161 | HID_KEY_BACKSPACE, HID_KEY_KEYPAD_0, HID_KEY_KEYPAD_ENTER}; 162 | 163 | for (int i = 0; i < 4; i++) { 164 | for (int j = 0; j < 3; j++) { 165 | row = i * 6; 166 | col = j * 4; 167 | kb_report.keyboard.keycode = numbpad[i * 3 + j]; 168 | overlay.setMembraneReport(row, col, height, width, &kb_report); 169 | } 170 | } 171 | 172 | //------------- Left Pad -------------// 173 | height = 3; 174 | width = 2; 175 | 176 | // row 1 177 | row = 0; 178 | col = 14; 179 | 180 | ik_report_keyboard_t const first_row[] = { 181 | {0, HID_KEY_KEYPAD_ADD}, 182 | {0, HID_KEY_KEYPAD_SUBTRACT}, 183 | {KEYBOARD_MODIFIER_LEFTSHIFT, HID_KEY_4}, 184 | {0, HID_KEY_ARROW_LEFT}, 185 | {0, HID_KEY_ARROW_RIGHT}}; 186 | 187 | overlay.setMembraneKeyboardArr(row, col, height, width, first_row, 188 | sizeof(first_row) / sizeof(first_row[0])); 189 | 190 | // row 2 191 | row = 3; 192 | col = 14; 193 | 194 | ik_report_keyboard_t const second_row[] = {{0, HID_KEY_KEYPAD_MULTIPLY}, 195 | {0, HID_KEY_KEYPAD_DIVIDE}, 196 | {0, HID_KEY_KEYPAD_DECIMAL}, 197 | {0, HID_KEY_ARROW_UP}, 198 | {0, HID_KEY_ARROW_DOWN}}; 199 | 200 | overlay.setMembraneKeyboardArr(row, col, height, width, second_row, 201 | sizeof(second_row) / sizeof(second_row[0])); 202 | 203 | // row 3 204 | row = 6; 205 | col = 14; 206 | 207 | kb_report.keyboard.modifier = 0; 208 | kb_report.keyboard.keycode = HID_KEY_KEYPAD_EQUAL; 209 | overlay.setMembraneReport(row, col, height, 2 * width, &kb_report); 210 | 211 | col += 2 * width; 212 | kb_report.keyboard.keycode = HID_KEY_SPACE; 213 | overlay.setMembraneReport(row, col, height, 2 * width, &kb_report); 214 | 215 | col += 2 * width; 216 | kb_report.keyboard.keycode = HID_KEY_TAB; 217 | overlay.setMembraneReport(row, col, height, width, &kb_report); 218 | 219 | // row 4 220 | row = 9; 221 | col = 14; 222 | 223 | kb_report.keyboard.modifier = 0; 224 | kb_report.keyboard.keycode = HID_KEY_CLEAR; 225 | overlay.setMembraneReport(row, col, height, 2 * width, &kb_report); 226 | col += 2 * width; 227 | 228 | kb_report.keyboard.keycode = HID_KEY_ESCAPE; 229 | overlay.setMembraneReport(row, col, height, width, &kb_report); 230 | col += 2 * width; 231 | 232 | kb_report.keyboard.modifier = KEYBOARD_MODIFIER_LEFTSHIFT; 233 | kb_report.keyboard.keycode = 0; 234 | 235 | // row 5 236 | row = 12; 237 | col = 17; 238 | 239 | mouse_report.mouse.buttons = 0; 240 | mouse_report.mouse.x = 0; 241 | mouse_report.mouse.y = -1; 242 | overlay.setMembraneReport(row, col, height, 2 * width, &mouse_report); 243 | 244 | // row 6 245 | row = 15; 246 | col = 14; 247 | 248 | ik_report_mouse_t const mouse_6th[] = { 249 | {0, -1, 0}, {0, -1, 0}, {MOUSE_BUTTON_LEFT, 0, 0}, {0, 1, 0}, {0, 1, 0}}; 250 | 251 | overlay.setMembraneMouseArr(row, col, height, width, mouse_6th, 252 | sizeof(mouse_6th) / sizeof(mouse_6th[0])); 253 | 254 | // row 7 255 | row = 18; 256 | col = 17; 257 | 258 | mouse_report.mouse.buttons = 0; 259 | mouse_report.mouse.x = 0; 260 | mouse_report.mouse.y = 1; 261 | overlay.setMembraneReport(row, col, height, 2 * width, &mouse_report); 262 | 263 | // row 8 264 | row = 21; 265 | col = 17; 266 | 267 | mouse_report.mouse.buttons = IK_REPORT_MOUSE_CLICK_HOLD; 268 | mouse_report.mouse.x = mouse_report.mouse.y = 0; 269 | overlay.setMembraneReport(row, col, height, 2 * width, &mouse_report); 270 | } 271 | 272 | //--------------------------------------------------------------------+ 273 | // Basic Writing 274 | //--------------------------------------------------------------------+ 275 | void IKOverlay::initStdBasicWriting(void) { 276 | IKOverlay &overlay = stdOverlays[IK_OVERLAY_BASIC_WRITING]; 277 | 278 | ik_report_t kb_report = {.type = IK_REPORT_TYPE_KEYBOARD, .keyboard = {0, 0}}; 279 | ik_report_t mouse_report = {.type = IK_REPORT_TYPE_MOUSE, .mouse = {0, 0, 0}}; 280 | 281 | int row, col; 282 | 283 | // for most keys, height = 3, width = 2 284 | int const height = 3; 285 | int const width = 2; 286 | 287 | //------------- First Row -------------// 288 | row = 0; 289 | col = 7 * width; 290 | 291 | mouse_report.mouse.buttons = MOUSE_BUTTON_LEFT; 292 | mouse_report.mouse.x = mouse_report.mouse.y = 0; 293 | overlay.setMembraneReport(row, col, height, width, &mouse_report); 294 | col += width + 1; 295 | 296 | mouse_report.mouse.buttons = 0; 297 | mouse_report.mouse.x = 0; 298 | mouse_report.mouse.y = -1; 299 | overlay.setMembraneReport(row, col, height, 2 * width, &mouse_report); 300 | col += 2 * width + 1; 301 | 302 | mouse_report.mouse.buttons = IK_REPORT_MOUSE_DOUBLE_CLICK; 303 | mouse_report.mouse.x = mouse_report.mouse.y = 0; 304 | overlay.setMembraneReport(row, col, height, width, &mouse_report); 305 | 306 | //------------- Second Row -------------// 307 | row = 3; 308 | col = 0; 309 | 310 | ik_report_keyboard_t const kb_2nd[] = {{0, HID_KEY_ESCAPE}, 311 | {0, HID_KEY_TAB}, 312 | {KEYBOARD_MODIFIER_LEFTALT, 0}, 313 | {KEYBOARD_MODIFIER_LEFTGUI, 0}, 314 | {KEYBOARD_MODIFIER_LEFTCTRL, 0}}; 315 | 316 | overlay.setMembraneKeyboardArr(row, col, height, width, kb_2nd, 317 | sizeof(kb_2nd) / sizeof(kb_2nd[0])); 318 | 319 | // mouse 320 | col = 7 * width; 321 | 322 | ik_report_mouse_t const mouse_2nd[] = { 323 | {0, -1, 0}, {0, -1, 0}, {MOUSE_BUTTON_LEFT, 0, 0}, {0, 1, 0}, {0, 1, 0}}; 324 | 325 | overlay.setMembraneMouseArr(row, col, height, width, mouse_2nd, 326 | sizeof(mouse_2nd) / sizeof(mouse_2nd[0])); 327 | 328 | //------------- Third Row -------------// 329 | row = 6; 330 | col = 0; 331 | 332 | ik_report_keyboard_t const kb_3rd[] = { 333 | {0, HID_KEY_PERIOD}, 334 | {0, HID_KEY_COMMA}, 335 | {0, HID_KEY_APOSTROPHE}, 336 | {KEYBOARD_MODIFIER_LEFTSHIFT, HID_KEY_1}, 337 | {KEYBOARD_MODIFIER_LEFTSHIFT, HID_KEY_SLASH}, 338 | {0, HID_KEY_MINUS}}; 339 | 340 | overlay.setMembraneKeyboardArr(row, col, height, width, kb_3rd, 341 | sizeof(kb_3rd) / sizeof(kb_3rd[0])); 342 | 343 | // mouse 344 | col = 7 * width; 345 | 346 | mouse_report.mouse.buttons = IK_REPORT_MOUSE_CLICK_HOLD; 347 | mouse_report.mouse.x = mouse_report.mouse.y = 0; 348 | overlay.setMembraneReport(row, col, height, width, &mouse_report); 349 | col += width + 1; 350 | 351 | mouse_report.mouse.buttons = 0; 352 | mouse_report.mouse.x = 0; 353 | mouse_report.mouse.y = 1; 354 | overlay.setMembraneReport(row, col, height, 2 * width, &mouse_report); 355 | col += 2 * width + 1; 356 | 357 | mouse_report.mouse.buttons = MOUSE_BUTTON_RIGHT; 358 | mouse_report.mouse.x = mouse_report.mouse.y = 0; 359 | overlay.setMembraneReport(row, col, height, width, &mouse_report); 360 | 361 | //------------- Fourth Row -------------// 362 | row = 9; 363 | col = 0; 364 | 365 | kb_report.keyboard.modifier = 0; 366 | for (int i = 0; i < 10; i++) { 367 | kb_report.keyboard.keycode = HID_KEY_1 + i; 368 | overlay.setMembraneReport(row, col, height, width, &kb_report); 369 | col += width; 370 | } 371 | 372 | kb_report.keyboard.keycode = HID_KEY_BACKSPACE; 373 | overlay.setMembraneReport(row, col, height, 2 * width, &kb_report); 374 | 375 | //------------- Fifth Row -------------// 376 | row = 12; 377 | col = 3; // first key is empty 378 | 379 | overlay.initQwertyRow(row, col, height, width); 380 | 381 | //------------- Sixth Row -------------// 382 | row = 15; 383 | col = 0; 384 | 385 | kb_report.keyboard.modifier = 0; 386 | kb_report.keyboard.keycode = HID_KEY_CAPS_LOCK; 387 | overlay.setMembraneReport(row, col, height, width, &kb_report); 388 | col += width; 389 | 390 | overlay.initAsdfghRow(row, col, height, width); 391 | col += 9 * width; 392 | 393 | kb_report.keyboard.keycode = HID_KEY_ENTER; 394 | overlay.setMembraneReport(row, col, height, 2 * width, &kb_report); 395 | 396 | //------------- Seventh Row -------------// 397 | row = 18; 398 | col = 0; 399 | 400 | kb_report.keyboard.modifier = KEYBOARD_MODIFIER_LEFTSHIFT; 401 | kb_report.keyboard.keycode = 0; 402 | overlay.setMembraneReport(row, col, height, 2 * width, &kb_report); 403 | col += 2 * width; 404 | 405 | overlay.initZxcvbnRow(row, col, height, width); 406 | col += 7 * width; 407 | 408 | kb_report.keyboard.modifier = KEYBOARD_MODIFIER_LEFTSHIFT; 409 | kb_report.keyboard.keycode = 0; 410 | overlay.setMembraneReport(row, col, height, 2 * width, &kb_report); 411 | 412 | //------------- Eighth Row -------------// 413 | row = 21; 414 | col = 8; 415 | 416 | kb_report.keyboard.modifier = 0; 417 | kb_report.keyboard.keycode = HID_KEY_SPACE; 418 | overlay.setMembraneReport(row, col, height, 3 * width, &kb_report); 419 | 420 | col += 4 * width; 421 | 422 | ik_report_keyboard_t const eighth_row[] = {{0, HID_KEY_ARROW_LEFT}, 423 | {0, HID_KEY_ARROW_RIGHT}, 424 | {0, HID_KEY_ARROW_UP}, 425 | {0, HID_KEY_ARROW_DOWN}}; 426 | 427 | overlay.setMembraneKeyboardArr(row, col, height, width, eighth_row, 428 | sizeof(eighth_row) / sizeof(eighth_row[0])); 429 | } 430 | 431 | //--------------------------------------------------------------------+ 432 | // Mouse Overlay 433 | //--------------------------------------------------------------------+ 434 | void IKOverlay::initStdMouseAccess(void) { 435 | IKOverlay &overlay = stdOverlays[IK_OVERLAY_MOUSE_ACCESS]; 436 | 437 | ik_report_t kb_report = {.type = IK_REPORT_TYPE_KEYBOARD, .keyboard = {0, 0}}; 438 | ik_report_t mouse_report = {.type = IK_REPORT_TYPE_MOUSE, .mouse = {0, 0, 0}}; 439 | 440 | int col, row; 441 | int const height = 6; 442 | int const width = 4; 443 | 444 | //------------- First Row -------------// 445 | col = 0; 446 | 447 | row = 0; 448 | mouse_report.mouse.buttons = MOUSE_BUTTON_RIGHT; 449 | overlay.setMembraneReport(row, col, height, width, &mouse_report); 450 | 451 | col = 20; 452 | overlay.setMembraneReport(row, col, height, width, &mouse_report); 453 | 454 | col = 10; 455 | kb_report.keyboard.modifier = 0; 456 | kb_report.keyboard.keycode = 457 | HID_KEY_ESCAPE; // TODO probably mouse related esc and not esc key ? 458 | overlay.setMembraneReport(row, col, height / 2, width, &kb_report); 459 | 460 | //------------- Second Row -------------// 461 | row = 6; 462 | 463 | col = 0; 464 | mouse_report.mouse.buttons = IK_REPORT_MOUSE_CLICK_HOLD; 465 | overlay.setMembraneReport(row, col, height, width, &mouse_report); 466 | 467 | col = 20; 468 | overlay.setMembraneReport(row, col, height, width, &mouse_report); 469 | 470 | col = 6; 471 | ik_report_mouse_t const mouse_2nd[] = {{0, -1, -1}, {0, 0, -1}, {0, 1, -1}}; 472 | 473 | overlay.setMembraneMouseArr(row, col, height, width, mouse_2nd, 474 | sizeof(mouse_2nd) / sizeof(mouse_2nd[0])); 475 | 476 | //------------- Third Row -------------// 477 | row = 12; 478 | 479 | col = 0; 480 | mouse_report.mouse.buttons = IK_REPORT_MOUSE_DOUBLE_CLICK; 481 | overlay.setMembraneReport(row, col, height, width, &mouse_report); 482 | 483 | col = 20; 484 | overlay.setMembraneReport(row, col, height, width, &mouse_report); 485 | 486 | col = 6; 487 | ik_report_mouse_t const mouse_3rd[] = { 488 | {0, -1, 0}, 489 | {MOUSE_BUTTON_LEFT, 0, 0}, 490 | {0, 1, 0}, 491 | }; 492 | 493 | overlay.setMembraneMouseArr(row, col, height, width, mouse_3rd, 494 | sizeof(mouse_3rd) / sizeof(mouse_3rd[0])); 495 | 496 | //------------- Fourth Row -------------// 497 | row = 18; 498 | 499 | col = 0; 500 | mouse_report.mouse.buttons = MOUSE_BUTTON_LEFT; 501 | overlay.setMembraneReport(row, col, height, width, &mouse_report); 502 | 503 | col = 20; 504 | overlay.setMembraneReport(row, col, height, width, &mouse_report); 505 | 506 | col = 6; 507 | ik_report_mouse_t const mouse_4th[] = { 508 | {0, -1, 1}, 509 | {0, 0, 1}, 510 | {0, 1, 1}, 511 | }; 512 | 513 | overlay.setMembraneMouseArr(row, col, height, width, mouse_4th, 514 | sizeof(mouse_4th) / sizeof(mouse_4th[0])); 515 | } 516 | 517 | // --------------------------------------------------------------------+ 518 | // Qwerty Overlay 519 | //--------------------------------------------------------------------+ 520 | void IKOverlay::initStdQwerty(void) { 521 | IKOverlay &overlay = stdOverlays[IK_OVERLAY_QWERTY]; 522 | 523 | ik_report_t report; 524 | report.type = IK_REPORT_TYPE_KEYBOARD; 525 | report.keyboard.modifier = 0; 526 | 527 | int col, row; 528 | int const height = 3; 529 | int const width = 2; 530 | 531 | //------------- First Row -------------// 532 | row = 0; 533 | col = 0; 534 | 535 | ik_report_keyboard_t const first_row[] = { 536 | {0, HID_KEY_ESCAPE}, 537 | {0, HID_KEY_TAB}, 538 | {0, HID_KEY_GRAVE}, 539 | {0, HID_KEY_NUM_LOCK}, 540 | {0, 0}, // TODO what is NUMPAD? 541 | {0, HID_KEY_INSERT}, 542 | {0, HID_KEY_HOME}, 543 | {0, HID_KEY_END}, 544 | {0, 0}, // TODO smart typing 545 | {0, HID_KEY_PAGE_UP}, 546 | {0, HID_KEY_PAGE_DOWN}, 547 | {0, HID_KEY_DELETE}, 548 | }; 549 | 550 | overlay.setMembraneKeyboardArr(row, col, height, width, first_row, 551 | sizeof(first_row) / sizeof(first_row[0])); 552 | 553 | //------------- Second Row -------------// 554 | row = 3; 555 | col = 0; 556 | 557 | report.keyboard.modifier = 0; 558 | for (int i = 0; i < 12; i++) { 559 | report.keyboard.keycode = HID_KEY_F1 + i; 560 | overlay.setMembraneReport(row, col, height, width, &report); 561 | col += width; 562 | } 563 | 564 | // Row 3 to 8 565 | initStdQwertyRow3to8(overlay, false); 566 | } 567 | 568 | void IKOverlay::initStdQwertyRow3to8(IKOverlay &overlay, bool is_web) { 569 | ik_report_t report; 570 | report.type = IK_REPORT_TYPE_KEYBOARD; 571 | report.keyboard.modifier = 0; 572 | 573 | int col, row; 574 | int const height = 3; 575 | int const width = 2; 576 | 577 | //------------- Third Row -------------// 578 | row = 6; 579 | col = 0; 580 | 581 | report.keyboard.modifier = 0; 582 | for (int i = 0; i < 10; i++) { 583 | report.keyboard.keycode = HID_KEY_1 + i; 584 | overlay.setMembraneReport(row, col, height, width, &report); 585 | col += width; 586 | } 587 | 588 | report.keyboard.keycode = HID_KEY_MINUS; 589 | overlay.setMembraneReport(row, col, height, width, &report); 590 | col += width; 591 | 592 | report.keyboard.keycode = HID_KEY_EQUAL; 593 | overlay.setMembraneReport(row, col, height, width, &report); 594 | 595 | //------------- Fourth Row -------------// 596 | row = 9; 597 | col = 0; 598 | 599 | overlay.initQwertyRow(row, col, height, width); 600 | col = 10 * width; 601 | 602 | report.keyboard.modifier = 0; 603 | report.keyboard.keycode = HID_KEY_BACKSPACE; 604 | overlay.setMembraneReport(row, col, height, 2 * width, &report); 605 | 606 | //------------- Fifth Row -------------// 607 | row = 12; 608 | col = 0; 609 | 610 | overlay.initAsdfghRow(row, col, height, width); 611 | col = 9 * width; 612 | 613 | // mouse report 614 | ik_report_mouse_t const mouse_5th[] = {{0, -1, -1}, {0, 0, -1}, {0, 1, -1}}; 615 | overlay.setMembraneMouseArr(row, col, height, width, mouse_5th, 616 | sizeof(mouse_5th) / sizeof(mouse_5th[0])); 617 | 618 | //------------- Sixth Row -------------// 619 | row = 15; 620 | col = 0; 621 | 622 | overlay.initZxcvbnRow(row, col, height, width); 623 | col = 7 * width; 624 | 625 | ik_report_keyboard_t sixth_row[] = {{0, HID_KEY_SEMICOLON}, 626 | {0, HID_KEY_APOSTROPHE}}; 627 | overlay.setMembraneKeyboardArr(row, col, height, width, sixth_row, 628 | sizeof(sixth_row) / sizeof(sixth_row[0])); 629 | col += 2 * width; 630 | 631 | // more mouse 632 | ik_report_mouse_t const mouse_6th[] = { 633 | {0, -1, 0}, 634 | {MOUSE_BUTTON_LEFT, 0, 0}, // left click 635 | {0, 1, 0}}; 636 | overlay.setMembraneMouseArr(row, col, height, width, mouse_6th, 637 | sizeof(mouse_6th) / sizeof(mouse_6th[0])); 638 | 639 | //------------- Seventh Row -------------// 640 | row = 18; 641 | col = 0; 642 | 643 | ik_report_keyboard_t seventh_row[] = {{0, HID_KEY_CAPS_LOCK}, 644 | {KEYBOARD_MODIFIER_LEFTSHIFT, 0}, 645 | {KEYBOARD_MODIFIER_LEFTSHIFT, 0}, 646 | {0, HID_KEY_SPACE}, 647 | {0, HID_KEY_SPACE}, 648 | {0, HID_KEY_SPACE}, 649 | {0, HID_KEY_COMMA}, 650 | {0, HID_KEY_PERIOD}, 651 | {0, HID_KEY_SLASH}}; 652 | 653 | // default is std, slightly changes if web overlay 654 | if (is_web) { 655 | seventh_row[3].keycode = HID_KEY_PAGE_UP; 656 | seventh_row[6].keycode = HID_KEY_PAGE_DOWN; 657 | seventh_row[7].keycode = HID_KEY_COMMA; 658 | seventh_row[8].keycode = HID_KEY_PERIOD; 659 | } 660 | 661 | overlay.setMembraneKeyboardArr(row, col, height, width, seventh_row, 662 | sizeof(seventh_row) / sizeof(seventh_row[0])); 663 | col += 9 * width; 664 | 665 | // mouse report 666 | ik_report_mouse_t const mouse_7th[] = {{0, -1, 1}, {0, 0, 1}, {0, 1, 1}}; 667 | overlay.setMembraneMouseArr(row, col, height, width, mouse_7th, 668 | sizeof(mouse_7th) / sizeof(mouse_7th[0])); 669 | 670 | //------------- Eighth Row -------------// 671 | row = 21; 672 | col = 0; 673 | 674 | ik_report_keyboard_t eighth_row[] = { 675 | {KEYBOARD_MODIFIER_LEFTCTRL, 0}, 676 | {KEYBOARD_MODIFIER_LEFTALT, 0}, 677 | {KEYBOARD_MODIFIER_LEFTGUI, 0}, 678 | {0, HID_KEY_ARROW_LEFT}, 679 | {0, HID_KEY_ARROW_RIGHT}, 680 | {0, HID_KEY_ARROW_UP}, 681 | {0, HID_KEY_ARROW_DOWN}, 682 | {0, HID_KEY_ENTER}, 683 | {0, HID_KEY_ENTER}, 684 | }; 685 | overlay.setMembraneKeyboardArr(row, col, height, width, eighth_row, 686 | sizeof(eighth_row) / sizeof(eighth_row[0])); 687 | col += 9 * width; 688 | 689 | ik_report_mouse_t const mouse_8th[] = {{IK_REPORT_MOUSE_DOUBLE_CLICK, 0, 0}, 690 | {MOUSE_BUTTON_RIGHT, 0, 0}, 691 | {IK_REPORT_MOUSE_CLICK_HOLD, 0, 0}}; 692 | overlay.setMembraneMouseArr(row, col, height, width, mouse_8th, 693 | sizeof(mouse_8th) / sizeof(mouse_8th[0])); 694 | } 695 | //--------------------------------------------------------------------+ 696 | // Alphabet Overlay 697 | //--------------------------------------------------------------------+ 698 | void IKOverlay::initStdAlphabet(void) { 699 | IKOverlay &overlay = stdOverlays[IK_OVERLAY_ALPHABET]; 700 | 701 | ik_report_t report; 702 | report.type = IK_REPORT_TYPE_KEYBOARD; 703 | report.keyboard.modifier = 0; 704 | 705 | int row, col; 706 | int const height = 4; 707 | int width = 3; 708 | 709 | //------------- First Row -------------// 710 | row = 0; 711 | col = 0; 712 | width = 4; 713 | 714 | ik_report_keyboard_t const first_row[] = { 715 | {0, HID_KEY_ESCAPE}, {0, HID_KEY_CAPS_LOCK}, {0, HID_KEY_BACKSPACE}}; 716 | 717 | overlay.setMembraneKeyboardArr(row, col, height, width, first_row, 718 | sizeof(first_row) / sizeof(first_row[0])); 719 | 720 | // Arrow 721 | width = 3; 722 | report.keyboard.keycode = HID_KEY_ARROW_LEFT; 723 | overlay.setMembraneReport(1, 14, height, width, &report); 724 | 725 | report.keyboard.keycode = HID_KEY_ARROW_UP; 726 | overlay.setMembraneReport(0, 18, height, width, &report); 727 | 728 | report.keyboard.keycode = HID_KEY_ARROW_RIGHT; 729 | overlay.setMembraneReport(1, 21, height, width, &report); 730 | 731 | report.keyboard.keycode = HID_KEY_ARROW_DOWN; 732 | overlay.setMembraneReport(4, 18, height, width, &report); 733 | 734 | //----------------- Second Row -------------// 735 | row = 4; 736 | col = 1; 737 | width = 2; 738 | 739 | report.keyboard.keycode = HID_KEY_PERIOD; 740 | overlay.setMembraneReport(row, col, height, width, &report); 741 | col += width; 742 | 743 | report.keyboard.keycode = HID_KEY_COMMA; 744 | overlay.setMembraneReport(row, col, height, width, &report); 745 | col += width; 746 | 747 | width = 3; // although the label is the same, actual test is 3 748 | 749 | report.keyboard.keycode = HID_KEY_SLASH; 750 | report.keyboard.modifier = KEYBOARD_MODIFIER_LEFTSHIFT; 751 | overlay.setMembraneReport(row, col, height, width, &report); 752 | col += width; 753 | 754 | report.keyboard.keycode = HID_KEY_1; 755 | report.keyboard.modifier = KEYBOARD_MODIFIER_LEFTSHIFT; 756 | overlay.setMembraneReport(row, col, height, width, &report); 757 | 758 | // Make sure all the alphabet is lowercase starting from here 759 | report.keyboard.modifier = 0; 760 | 761 | //----------------- Third Row -------------// 762 | row = 8; 763 | col = 0; 764 | width = 3; 765 | 766 | for (int i = 0; i < 8; i++) { 767 | report.keyboard.keycode = HID_KEY_A + i; 768 | overlay.setMembraneReport(row, col, height, width, &report); 769 | col += width; 770 | } 771 | 772 | //----------------- Fourth Row ------------- 773 | row = 12; 774 | col = 0; 775 | 776 | for (int i = 0; i < 8; i++) { 777 | report.keyboard.keycode = HID_KEY_I + i; 778 | overlay.setMembraneReport(row, col, height, width, &report); 779 | col += width; 780 | } 781 | 782 | //----------------- Fifth Row -------------// 783 | row = 16; 784 | col = 0; 785 | 786 | for (int i = 0; i < 6; i++) { 787 | report.keyboard.keycode = HID_KEY_Q + i; 788 | overlay.setMembraneReport(row, col, height, width, &report); 789 | col += width; 790 | } 791 | 792 | report.keyboard.keycode = HID_KEY_ENTER; 793 | overlay.setMembraneReport(row, col, height, 2 * width, &report); 794 | 795 | //------------- Sixth Row -------------// 796 | row = 20; 797 | col = 0; 798 | 799 | ik_report_keyboard_t const sixth_row[] = {{KEYBOARD_MODIFIER_LEFTSHIFT, 0}, 800 | {0, HID_KEY_W}, 801 | {0, HID_KEY_X}, 802 | {0, HID_KEY_Y}, 803 | {0, HID_KEY_Z}, 804 | {KEYBOARD_MODIFIER_LEFTSHIFT, 0}}; 805 | 806 | overlay.setMembraneKeyboardArr(row, col, height, width, sixth_row, 807 | sizeof(sixth_row) / sizeof(sixth_row[0])); 808 | col += 6 * width; 809 | 810 | report.keyboard.modifier = 0; 811 | report.keyboard.keycode = HID_KEY_SPACE; 812 | overlay.setMembraneReport(row, col, height, 2 * width, &report); 813 | } 814 | 815 | void IKOverlay::setMembraneKeyboardArr(int row, int col, int height, int width, 816 | const ik_report_keyboard_t kbd_report[], 817 | uint8_t count) { 818 | for (uint8_t i = 0; i < count; i++) { 819 | ik_report_t report; 820 | report.type = IK_REPORT_TYPE_KEYBOARD; 821 | report.keyboard = kbd_report[i]; 822 | 823 | setMembraneReport(row, col, height, width, &report); 824 | col += width; 825 | } 826 | } 827 | 828 | void IKOverlay::setMembraneMouseArr(int row, int col, int height, int width, 829 | ik_report_mouse_t const mouse_report[], 830 | uint8_t count) { 831 | for (uint8_t i = 0; i < count; i++) { 832 | ik_report_t report; 833 | report.type = IK_REPORT_TYPE_MOUSE; 834 | report.mouse = mouse_report[i]; 835 | 836 | setMembraneReport(row, col, height, width, &report); 837 | col += width; 838 | } 839 | } 840 | 841 | void IKOverlay::initQwertyRow(int row, int col, int height, int width) { 842 | ik_report_keyboard_t kbd_item[] = { 843 | {0, HID_KEY_Q}, {0, HID_KEY_W}, {0, HID_KEY_E}, {0, HID_KEY_R}, 844 | {0, HID_KEY_T}, {0, HID_KEY_Y}, {0, HID_KEY_U}, {0, HID_KEY_I}, 845 | {0, HID_KEY_O}, {0, HID_KEY_P}}; 846 | 847 | setMembraneKeyboardArr(row, col, height, width, kbd_item, 848 | sizeof(kbd_item) / sizeof(kbd_item[0])); 849 | } 850 | 851 | void IKOverlay::initAsdfghRow(int row, int col, int height, int width) { 852 | ik_report_keyboard_t kbd_item[] = { 853 | {0, HID_KEY_A}, {0, HID_KEY_S}, {0, HID_KEY_D}, 854 | {0, HID_KEY_F}, {0, HID_KEY_G}, {0, HID_KEY_H}, 855 | {0, HID_KEY_J}, {0, HID_KEY_K}, {0, HID_KEY_L}}; 856 | 857 | setMembraneKeyboardArr(row, col, height, width, kbd_item, 858 | sizeof(kbd_item) / sizeof(kbd_item[0])); 859 | } 860 | 861 | void IKOverlay::initZxcvbnRow(int row, int col, int height, int width) { 862 | ik_report_keyboard_t kb_item[] = { 863 | {0, HID_KEY_Z}, {0, HID_KEY_X}, {0, HID_KEY_C}, {0, HID_KEY_V}, 864 | {0, HID_KEY_B}, {0, HID_KEY_N}, {0, HID_KEY_M}}; 865 | 866 | setMembraneKeyboardArr(row, col, height, width, kb_item, 867 | sizeof(kb_item) / sizeof(kb_item[0])); 868 | } 869 | -------------------------------------------------------------------------------- /src/IKOverlay.h: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2023 Ha Thach (thach@tinyusb.org) for Adafruit Industries 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | #ifndef ADAFRUIT_INTELLIKEYS_IKOVERLAY_H 26 | #define ADAFRUIT_INTELLIKEYS_IKOVERLAY_H 27 | 28 | #include "intellikeysdefs.h" 29 | 30 | /* The standard overlays 31 | Standard_Overlay_0_Name Web Access USB Overlay 32 | Standard_Overlay_1_Name Setup USB Overlay 33 | Standard_Overlay_2_Name Math Access USB Overlay 34 | Standard_Overlay_3_Name Alphabet USB Overlay 35 | Standard_Overlay_4_Name Mouse Access USB Overlay 36 | Standard_Overlay_5_Name QWERTY USB Overlay 37 | Standard_Overlay_6_Name Basic Writing USB Overlay 38 | Standard_Overlay_7_Name none 39 | */ 40 | 41 | #define IK_OVERLAY_WEB_ACCESS 0 42 | #define IK_OVERLAY_SETUP 1 43 | #define IK_OVERLAY_MATH_ACCESS 2 44 | #define IK_OVERLAY_ALPHABET 3 45 | #define IK_OVERLAY_MOUSE_ACCESS 4 46 | #define IK_OVERLAY_QWERTY 5 47 | #define IK_OVERLAY_BASIC_WRITING 6 48 | 49 | enum { IK_REPORT_TYPE_NONE = 0, IK_REPORT_TYPE_KEYBOARD, IK_REPORT_TYPE_MOUSE }; 50 | 51 | enum { 52 | IK_REPORT_MOUSE_DOUBLE_CLICK = (1u << 5), 53 | IK_REPORT_MOUSE_CLICK_HOLD = (1u << 6), 54 | }; 55 | 56 | typedef struct __attribute__((packed)) { 57 | uint8_t modifier; 58 | uint8_t keycode; 59 | } ik_report_keyboard_t; 60 | 61 | typedef struct __attribute__((packed)) { 62 | uint8_t buttons; // 63 | int8_t x; 64 | int8_t y; 65 | } ik_report_mouse_t; 66 | 67 | typedef struct __attribute__((packed)) { 68 | uint8_t type; // 0: for none, 1 for keyboard, 2 for mouse 69 | union { 70 | ik_report_keyboard_t keyboard; 71 | ik_report_mouse_t mouse; 72 | }; 73 | } ik_report_t; 74 | 75 | class IKOverlay { 76 | public: 77 | IKOverlay(); 78 | 79 | // Init all std overlays 80 | static void initStandardOverlays(void); 81 | 82 | void setMembraneReport(int top_row, int top_col, int height, int width, 83 | ik_report_t *report); 84 | 85 | void getSwitchReport(int nswitch, ik_report_t *report); 86 | void getMembraneReport(int row, int col, ik_report_t *report); 87 | 88 | void setMembraneKeyboardArr(int row, int col, int height, int width, 89 | const ik_report_keyboard_t kbd_report[], 90 | uint8_t count); 91 | void setMembraneMouseArr(int row, int col, int height, int width, 92 | ik_report_mouse_t const mouse_report[], 93 | uint8_t count); 94 | 95 | private: 96 | ik_report_t _membrane[IK_RESOLUTION_X][IK_RESOLUTION_Y]; 97 | 98 | // init each std overlays 99 | static void initStdWebAccess(void); 100 | static void initStdMathAccess(void); 101 | static void initStdAlphabet(void); 102 | static void initStdMouseAccess(void); 103 | static void initStdQwerty(void); 104 | static void initStdBasicWriting(void); 105 | 106 | static void initStdQwertyRow3to8(IKOverlay &overlay, bool is_web); 107 | 108 | // init row QWERTY 109 | void initQwertyRow(int row, int col, int height, int width); 110 | void initAsdfghRow(int row, int col, int height, int width); 111 | void initZxcvbnRow(int row, int col, int height, int width); 112 | }; 113 | 114 | extern IKOverlay stdOverlays[7]; 115 | 116 | #endif // ADAFRUIT_INTELLIKEYS_IKOVERLAY_H 117 | -------------------------------------------------------------------------------- /src/IKSettings.cpp: -------------------------------------------------------------------------------- 1 | // IKSettings.cpp: implementation of the IKSettings class. 2 | // 3 | ////////////////////////////////////////////////////////////////////// 4 | 5 | // #include "IKCommon.h" 6 | #include "IKSettings.h" 7 | // #include "IKFile.h" 8 | 9 | // #include "IKUtil.h" 10 | 11 | // #include 12 | 13 | #define TEXT(_x) (_x) 14 | 15 | ////////////////////////////////////////////////////////////////////// 16 | // Construction/Destruction 17 | //////////////////////////////////////////////////////////////////// 18 | 19 | static IKSettings settings; 20 | 21 | IKSettings *IKSettings::GetSettings() { return &settings; } 22 | 23 | // copy ctor 24 | 25 | IKSettings::IKSettings() 26 | : 27 | 28 | m_iResponseRate(kSettingsRateHigh), 29 | 30 | m_bRequiredLiftOff(false), 31 | 32 | m_bUseSystemRepeatSettings(true), 33 | 34 | m_iKeySoundVolume(kSettingsKeysound2), 35 | 36 | m_iRepeatRate(kSettingsRateHigh), 37 | 38 | m_bRepeat(true), 39 | 40 | m_bShowModeWarning(true), 41 | 42 | m_bRepeatLatching(false), 43 | 44 | m_iShiftKeyAction(kSettingsShiftLatching), 45 | 46 | m_iMouseSpeed(kSettingsRateHigh), 47 | 48 | m_bSmartTyping(false), 49 | 50 | m_iDataSendRate(kSettingsRateHigh), 51 | 52 | m_iMakeBreakRate(kSettingsRateHigh), 53 | 54 | m_iIndicatorLights(kSettings6lights), 55 | 56 | m_iMode(kSettingsModeLastSentOverlay), 57 | 58 | m_iUseThisSwitchSetting(0), 59 | 60 | // m_sUseThisOverlay (TEXT("")) 61 | 62 | m_sLastSent(TEXT("")), m_sLastSentBy(TEXT("")), 63 | 64 | m_bButAllowOverlays(true) 65 | 66 | { 67 | SetToDefault(); 68 | } 69 | 70 | IKSettings::~IKSettings() {} 71 | 72 | IKSettings &IKSettings ::operator=(const IKSettings &rhs) { 73 | m_iResponseRate = rhs.m_iResponseRate; 74 | m_bRequiredLiftOff = rhs.m_bRequiredLiftOff; 75 | m_bUseSystemRepeatSettings = rhs.m_bUseSystemRepeatSettings; 76 | m_iKeySoundVolume = rhs.m_iKeySoundVolume; 77 | m_iRepeatRate = rhs.m_iRepeatRate; 78 | m_bRepeat = rhs.m_bRepeat; 79 | m_bRepeatLatching = rhs.m_bRepeatLatching; 80 | m_iShiftKeyAction = rhs.m_iShiftKeyAction; 81 | m_iMouseSpeed = rhs.m_iMouseSpeed; 82 | m_bSmartTyping = rhs.m_bSmartTyping; 83 | m_iDataSendRate = rhs.m_iDataSendRate; 84 | m_iMakeBreakRate = rhs.m_iMakeBreakRate; 85 | m_iIndicatorLights = rhs.m_iIndicatorLights; 86 | // m_group = rhs.m_group; 87 | // m_student = rhs.m_student; 88 | m_iMode = rhs.m_iMode; 89 | m_iUseThisSwitchSetting = rhs.m_iUseThisSwitchSetting; 90 | m_sUseThisOverlay = rhs.m_sUseThisOverlay; 91 | 92 | m_keyMap = rhs.m_keyMap; 93 | 94 | m_sLastSent = rhs.m_sLastSent; 95 | m_sLastSentBy = rhs.m_sLastSentBy; 96 | 97 | m_bShowModeWarning = rhs.m_bShowModeWarning; 98 | 99 | m_bButAllowOverlays = rhs.m_bButAllowOverlays; 100 | 101 | return *this; 102 | } 103 | 104 | bool IKSettings ::operator!=(const IKSettings &rhs) { return !(*this == rhs); } 105 | 106 | bool IKSettings ::operator==(const IKSettings &rhs) { 107 | return (m_iResponseRate == rhs.m_iResponseRate) && 108 | (m_bRequiredLiftOff == rhs.m_bRequiredLiftOff) && 109 | (m_bUseSystemRepeatSettings == rhs.m_bUseSystemRepeatSettings) && 110 | (m_iKeySoundVolume == rhs.m_iKeySoundVolume) && 111 | (m_iRepeatRate == rhs.m_iRepeatRate) && (m_bRepeat == rhs.m_bRepeat) && 112 | (m_bRepeatLatching == rhs.m_bRepeatLatching) && 113 | (m_iShiftKeyAction == rhs.m_iShiftKeyAction) && 114 | (m_iMouseSpeed == rhs.m_iMouseSpeed) && 115 | (m_bSmartTyping == rhs.m_bSmartTyping) && 116 | (m_iDataSendRate == rhs.m_iDataSendRate) && 117 | (m_iMakeBreakRate == rhs.m_iMakeBreakRate) && 118 | (m_iIndicatorLights == rhs.m_iIndicatorLights) && 119 | //( m_group == rhs.m_group 120 | //) 121 | //&& 122 | //( m_student == rhs.m_student 123 | //) 124 | //&& 125 | (m_iMode == rhs.m_iMode) && 126 | (m_iUseThisSwitchSetting == rhs.m_iUseThisSwitchSetting) && 127 | (m_sUseThisOverlay == rhs.m_sUseThisOverlay) && 128 | (m_sLastSent == rhs.m_sLastSent) && 129 | (m_sLastSentBy == rhs.m_sLastSentBy) && 130 | (m_bShowModeWarning == rhs.m_bShowModeWarning) && 131 | (m_bButAllowOverlays == rhs.m_bButAllowOverlays) && true; 132 | } 133 | 134 | bool IKSettings::Read(IKString filename) { 135 | // set to defaults first 136 | SetToDefault(); 137 | 138 | #if 0 139 | // load the file 140 | bool bLoaded = m_keyMap.Read(filename); 141 | #else 142 | bool bLoaded = false; 143 | #endif 144 | 145 | // extract loaded values 146 | 147 | if (bLoaded) { 148 | m_iResponseRate = GetIntValue(TEXT("Response Rate")); 149 | m_iRepeatRate = GetIntValue(TEXT("Repeat Rate")); 150 | m_iShiftKeyAction = GetIntValue(TEXT("Shift Key Action")); 151 | m_iMouseSpeed = GetIntValue(TEXT("Mouse Speed")); 152 | m_iDataSendRate = GetIntValue(TEXT("Data Send Rate")); 153 | m_iMakeBreakRate = GetIntValue(TEXT("Make Break Rate")); 154 | m_iIndicatorLights = 155 | kSettings6lights; // GetIntValue(TEXT("Indicator Lights")); 156 | 157 | m_bRequiredLiftOff = GetBoolValue(TEXT("Required Lift Off")); 158 | m_bUseSystemRepeatSettings = 159 | GetBoolValue(TEXT("Use System Repeat Settings")); 160 | m_iKeySoundVolume = GetIntValue(TEXT("Key Sound Volume")); 161 | m_bRepeat = GetBoolValue(TEXT("Repeat")); 162 | m_bRepeatLatching = GetBoolValue(TEXT("Repeat Latching")); 163 | m_bSmartTyping = GetBoolValue(TEXT("Smart Typing")); 164 | 165 | m_iMode = GetIntValue(TEXT("Mode")); 166 | m_iUseThisSwitchSetting = GetIntValue(TEXT("Use This Switch Setting")); 167 | m_sUseThisOverlay = GetStringValue(TEXT("Use This Overlay")); 168 | m_sLastSent = GetStringValue(TEXT("Last Sent")); 169 | m_sLastSentBy = GetStringValue(TEXT("Last Sent By")); 170 | 171 | m_bShowModeWarning = GetBoolValue(TEXT("Show Mode Warning")); 172 | m_bButAllowOverlays = GetBoolValue(TEXT("But Allow Overlays")); 173 | } 174 | 175 | return true; 176 | } 177 | 178 | void IKSettings::Write(IKString filename) { 179 | StoreValues(); 180 | 181 | // save the file 182 | #if 0 183 | m_keyMap.Write(filename); 184 | #endif 185 | } 186 | 187 | void IKSettings::Write() { 188 | StoreValues(); 189 | 190 | // save the file 191 | #if 0 192 | m_keyMap.Write(); 193 | #endif 194 | } 195 | 196 | int IKSettings::GetIntValue(TCHAR *pKey) { 197 | #if 0 198 | IKString str = GetStringValue(pKey); 199 | return IKUtil::StringToInt(str); 200 | #else 201 | return 0; 202 | #endif 203 | } 204 | 205 | void IKSettings::SetIntValue(TCHAR *pKey, int value) { 206 | #if 0 207 | m_keyMap.SetValue(pKey,value); 208 | #endif 209 | } 210 | 211 | bool IKSettings::GetBoolValue(TCHAR *pKey) { 212 | #if 0 213 | IKString str = GetStringValue(pKey); 214 | if(str.Compare(TEXT("true"))==0) 215 | 216 | return true; 217 | 218 | if(str.Compare(TEXT("TRUE"))==0) 219 | 220 | return true; 221 | 222 | #endif 223 | return false; 224 | } 225 | 226 | void IKSettings::SetBoolValue(TCHAR *pKey, bool bValue) { 227 | #if 0 228 | if (bValue) 229 | SetStringValue ( pKey, TEXT("TRUE")); 230 | else 231 | SetStringValue ( pKey, TEXT("FALSE")); 232 | #endif 233 | } 234 | 235 | IKString IKSettings::GetStringValue(TCHAR *pKey) { 236 | #if 0 237 | IKString str = m_keyMap.GetValueString(pKey); 238 | return str; 239 | #else 240 | return NULL; 241 | #endif 242 | } 243 | 244 | void IKSettings::SetStringValue(TCHAR *pKey, TCHAR *pValue) { 245 | #if 0 246 | m_keyMap.Add(pKey,pValue); 247 | #endif 248 | } 249 | 250 | void IKSettings::SetToDefault(bool bFeatureReset /*=false*/) { 251 | m_iResponseRate = kSettingsRateHigh; 252 | m_bRequiredLiftOff = false; 253 | m_bUseSystemRepeatSettings = true; 254 | m_iKeySoundVolume = kSettingsKeysound2; 255 | m_iRepeatRate = kSettingsRateHigh; 256 | m_bRepeat = true; 257 | m_bRepeatLatching = false; 258 | m_iShiftKeyAction = kSettingsShiftLatching; 259 | m_iMouseSpeed = kSettingsRateHigh; 260 | m_bSmartTyping = false; 261 | m_iDataSendRate = kSettingsRateHigh; 262 | m_iMakeBreakRate = kSettingsRateHigh; 263 | m_iIndicatorLights = kSettings6lights; 264 | m_iMode = kSettingsModeLastSentOverlay; 265 | m_iUseThisSwitchSetting = 0; 266 | m_sUseThisOverlay = TEXT(""); 267 | m_bShowModeWarning = true; 268 | m_bButAllowOverlays = true; 269 | 270 | if (!bFeatureReset) { 271 | m_sLastSent = TEXT(""); 272 | m_sLastSentBy = TEXT(""); 273 | } 274 | } 275 | 276 | void IKSettings::StoreValues() { 277 | // store new values 278 | #if 0 279 | SetIntValue ( TEXT("Repeat Rate"), m_iRepeatRate); 280 | SetIntValue ( TEXT("Shift Key Action"), m_iShiftKeyAction); 281 | SetIntValue ( TEXT("Response Rate"), m_iResponseRate); 282 | SetIntValue ( TEXT("Mouse Speed"), m_iMouseSpeed); 283 | SetIntValue ( TEXT("Data Send Rate"), m_iDataSendRate); 284 | SetIntValue ( TEXT("Make Break Rate"), m_iMakeBreakRate); 285 | SetIntValue ( TEXT("Indicator Lights"), m_iIndicatorLights); 286 | SetIntValue ( TEXT("Make Break Rate"), m_iDataSendRate); 287 | 288 | SetBoolValue ( TEXT("Required Lift Off"), m_bRequiredLiftOff); 289 | SetBoolValue ( TEXT("Use System Repeat Settings"), m_bUseSystemRepeatSettings); 290 | SetIntValue ( TEXT("Key Sound Volume"), m_iKeySoundVolume); 291 | SetBoolValue ( TEXT("Repeat"), m_bRepeat); 292 | SetBoolValue ( TEXT("Repeat Latching"), m_bRepeatLatching); 293 | SetBoolValue ( TEXT("Smart Typing"), m_bSmartTyping); 294 | 295 | SetIntValue ( TEXT("Mode"), m_iMode ); 296 | SetIntValue ( TEXT("Use This Switch Setting"), m_iUseThisSwitchSetting ); 297 | SetStringValue ( TEXT("Use This Overlay"), m_sUseThisOverlay ); 298 | SetStringValue ( TEXT("Last Sent"), m_sLastSent ); 299 | SetStringValue ( TEXT("Last Sent By"), m_sLastSentBy ); 300 | 301 | SetBoolValue ( TEXT("Show Mode Warning"), m_bShowModeWarning ); 302 | SetBoolValue ( TEXT("But Allow Overlays"), m_bButAllowOverlays ); 303 | #endif 304 | } 305 | 306 | ////////////////////////////////// 307 | // 308 | // copy ctor 309 | 310 | IKSettings::IKSettings(const IKSettings &src) { 311 | m_iResponseRate = src.m_iResponseRate; 312 | m_bRequiredLiftOff = src.m_bRequiredLiftOff; 313 | m_bUseSystemRepeatSettings = src.m_bUseSystemRepeatSettings; 314 | m_iKeySoundVolume = src.m_iKeySoundVolume; 315 | m_iRepeatRate = src.m_iRepeatRate; 316 | m_bRepeat = src.m_bRepeat; 317 | m_bRepeatLatching = src.m_bRepeatLatching; 318 | m_iShiftKeyAction = src.m_iShiftKeyAction; 319 | m_iMouseSpeed = src.m_iMouseSpeed; 320 | m_bSmartTyping = src.m_bSmartTyping; 321 | m_iDataSendRate = src.m_iDataSendRate; 322 | m_iMakeBreakRate = src.m_iMakeBreakRate; 323 | m_iIndicatorLights = src.m_iIndicatorLights; 324 | // m_group = rhs.m_group; 325 | // m_student = rhs.m_student; 326 | m_iMode = src.m_iMode; 327 | m_iUseThisSwitchSetting = src.m_iUseThisSwitchSetting; 328 | m_sUseThisOverlay = src.m_sUseThisOverlay; 329 | 330 | m_keyMap = src.m_keyMap; 331 | 332 | m_sLastSent = src.m_sLastSent; 333 | m_sLastSentBy = src.m_sLastSentBy; 334 | 335 | m_bShowModeWarning = src.m_bShowModeWarning; 336 | m_bButAllowOverlays = src.m_bButAllowOverlays; 337 | } 338 | -------------------------------------------------------------------------------- /src/IKSettings.h: -------------------------------------------------------------------------------- 1 | // IKSettings.h: interface for the IKSettings class. 2 | // 3 | ////////////////////////////////////////////////////////////////////// 4 | 5 | #if !defined(AFX_IKSETTINGS_H__2529EB67_16DF_4B22_B49F_7BE997C36C53__INCLUDED_) 6 | #define AFX_IKSETTINGS_H__2529EB67_16DF_4B22_B49F_7BE997C36C53__INCLUDED_ 7 | 8 | #include 9 | #include 10 | 11 | // #include "IKString.h" 12 | // #include "IKPrefs.h" 13 | 14 | #define IKPrefs int 15 | 16 | #define IKString char * 17 | #define TCHAR char 18 | 19 | enum { kSettingsRateLow = 1, kSettingsRateHigh = 15 }; 20 | 21 | enum { 22 | kSettingsShiftLatching = 0, 23 | kSettingsShiftLocking, 24 | kSettingsShiftNoLatch 25 | }; 26 | 27 | enum { kSettings3lights = 0, kSettings6lights }; 28 | 29 | enum { 30 | kSettingsKeysoundOff = 0, 31 | kSettingsKeysound1, 32 | kSettingsKeysound2, 33 | kSettingsKeysound3, 34 | kSettingsKeysound4 35 | }; 36 | 37 | enum { 38 | kSettingsModeLastSentOverlay = 0, 39 | kSettingsModeThisOverlay, 40 | kSettingsModeSwitch, 41 | kSettingsModeDiscover 42 | }; 43 | 44 | class IKSettings { 45 | public: 46 | IKSettings(); 47 | virtual ~IKSettings(); 48 | 49 | static IKSettings *GetSettings(); 50 | 51 | void Write(IKString filename); 52 | void Write(); 53 | bool Read(IKString filename); 54 | void SetToDefault(bool bFeatureReset = false); 55 | IKSettings &operator=(const IKSettings &rhs); 56 | bool operator==(const IKSettings &rhs); 57 | bool operator!=(const IKSettings &rhs); 58 | int GetIntValue(TCHAR *pKey); 59 | void SetIntValue(TCHAR *pKey, int value); 60 | bool GetBoolValue(TCHAR *pKey); 61 | void SetBoolValue(TCHAR *pKey, bool value); 62 | IKString GetStringValue(TCHAR *pKey); 63 | void SetStringValue(TCHAR *pKey, TCHAR *pValue); 64 | IKSettings(const IKSettings &src); // copy ctor 65 | 66 | int m_iResponseRate; 67 | bool m_bRequiredLiftOff; 68 | int m_iRepeatRate; 69 | bool m_bRepeat; 70 | bool m_bRepeatLatching; 71 | int m_iShiftKeyAction; 72 | int m_iMouseSpeed; 73 | bool m_bSmartTyping; 74 | int m_iDataSendRate; 75 | int m_iMakeBreakRate; 76 | int m_iIndicatorLights; 77 | int m_iKeySoundVolume; 78 | int m_iUseThisSwitchSetting; 79 | bool m_bUseSystemRepeatSettings; 80 | IKString m_sUseThisOverlay; 81 | int m_iMode; 82 | IKPrefs m_keyMap; 83 | IKString m_sLastSent; 84 | IKString m_sLastSentBy; 85 | bool m_bShowModeWarning; 86 | bool m_bButAllowOverlays; 87 | 88 | private: 89 | void StoreValues(); 90 | }; 91 | 92 | #endif // !defined(AFX_IKSETTINGS_H__2529EB67_16DF_4B22_B49F_7BE997C36C53__INCLUDED_) 93 | -------------------------------------------------------------------------------- /src/IKUniversal.h: -------------------------------------------------------------------------------- 1 | // 2 | // Definitions for all the intellikeys universal codes 3 | // 4 | 5 | #define UNIVERSAL_F1 0x01 6 | #define UNIVERSAL_F2 0x02 7 | #define UNIVERSAL_F3 0x03 8 | #define UNIVERSAL_F4 0x04 9 | #define UNIVERSAL_F5 0x05 10 | #define UNIVERSAL_F6 0x06 11 | #define UNIVERSAL_F7 0x07 12 | #define UNIVERSAL_F8 0x08 13 | #define UNIVERSAL_F9 0x09 14 | #define UNIVERSAL_F10 0x0a 15 | #define UNIVERSAL_F11 0x0b 16 | #define UNIVERSAL_F12 0x0c 17 | 18 | #define UNIVERSAL_F13 0x0d 19 | #define UNIVERSAL_PRINT_SCREEN 0x0d 20 | 21 | #define UNIVERSAL_F14 0x0e 22 | #define UNIVERSAL_SCROLL_LOCK 0x0e 23 | 24 | #define UNIVERSAL_F15 0x0f 25 | #define UNIVERSAL_PAUSE 0x0f 26 | 27 | #define UNIVERSAL_SPACE 0x20 28 | 29 | #define UNIVERSAL_NUMPAD_0 0x10 30 | #define UNIVERSAL_NUMPAD_1 0x11 31 | #define UNIVERSAL_NUMPAD_2 0x12 32 | #define UNIVERSAL_NUMPAD_3 0x13 33 | #define UNIVERSAL_NUMPAD_4 0x14 34 | #define UNIVERSAL_NUMPAD_5 0x15 35 | #define UNIVERSAL_NUMPAD_6 0x16 36 | #define UNIVERSAL_NUMPAD_7 0x17 37 | #define UNIVERSAL_NUMPAD_8 0x18 38 | #define UNIVERSAL_NUMPAD_9 0x19 39 | #define UNIVERSAL_NUMPAD_ADD 0x1a 40 | #define UNIVERSAL_NUMPAD_SUBTRACT 0x1b 41 | #define UNIVERSAL_NUMPAD_MULTIPLY 0x1c 42 | #define UNIVERSAL_NUMPAD_DIVIDE 0x1d 43 | #define UNIVERSAL_NUMPAD_EQUAL 0x1e 44 | #define UNIVERSAL_NUMPAD_ENTER 0x1f 45 | #define UNIVERSAL_NUMPAD_DECIMAL 0x21 46 | 47 | #define UNIVERSAL_INSERT 0x22 48 | #define UNIVERSAL_DELETE 0x23 49 | #define UNIVERSAL_UP_ARROW 0x24 50 | #define UNIVERSAL_DOWN_ARROW 0x25 51 | #define UNIVERSAL_LEFT_ARROW 0x26 52 | #define UNIVERSAL_RIGHT_ARROW 0x27 53 | #define UNIVERSAL_HOME 0x28 54 | #define UNIVERSAL_END 0x29 55 | #define UNIVERSAL_PAGE_UP 0x2a 56 | #define UNIVERSAL_PAGE_DOWN 0x2b 57 | #define UNIVERSAL_COMMA 0x2c 58 | #define UNIVERSAL_MINUS 0x2d 59 | #define UNIVERSAL_PERIOD 0x2e 60 | #define UNIVERSAL_SLASH 0x2f 61 | 62 | #define UNIVERSAL_0 0x30 63 | #define UNIVERSAL_1 0x31 64 | #define UNIVERSAL_2 0x32 65 | #define UNIVERSAL_3 0x33 66 | #define UNIVERSAL_4 0x34 67 | #define UNIVERSAL_5 0x35 68 | #define UNIVERSAL_6 0x36 69 | #define UNIVERSAL_7 0x37 70 | #define UNIVERSAL_8 0x38 71 | #define UNIVERSAL_9 0x39 72 | 73 | // #define UNIVERSAL_ 0x3a 74 | 75 | #define UNIVERSAL_SEMICOLON 0x3b 76 | 77 | // #define UNIVERSAL_ 0x3c 78 | 79 | #define UNIVERSAL_EQUALS 0x3d 80 | #define UNIVERSAL_TILDE 0x3e 81 | #define UNIVERSAL_QUOTE 0x3f 82 | 83 | // #define UNIVERSAL_ 0x40 84 | 85 | #define UNIVERSAL_A 0x41 86 | #define UNIVERSAL_B 0x42 87 | #define UNIVERSAL_C 0x43 88 | #define UNIVERSAL_D 0x44 89 | #define UNIVERSAL_E 0x45 90 | #define UNIVERSAL_F 0x46 91 | #define UNIVERSAL_G 0x47 92 | #define UNIVERSAL_H 0x48 93 | #define UNIVERSAL_I 0x49 94 | #define UNIVERSAL_J 0x4a 95 | #define UNIVERSAL_K 0x4b 96 | #define UNIVERSAL_L 0x4c 97 | #define UNIVERSAL_M 0x4d 98 | #define UNIVERSAL_N 0x4e 99 | #define UNIVERSAL_O 0x4f 100 | #define UNIVERSAL_P 0x50 101 | #define UNIVERSAL_Q 0x51 102 | #define UNIVERSAL_R 0x52 103 | #define UNIVERSAL_S 0x53 104 | #define UNIVERSAL_T 0x54 105 | #define UNIVERSAL_U 0x55 106 | #define UNIVERSAL_V 0x56 107 | #define UNIVERSAL_W 0x57 108 | #define UNIVERSAL_X 0x58 109 | #define UNIVERSAL_Y 0x59 110 | #define UNIVERSAL_Z 0x5a 111 | 112 | #define UNIVERSAL_LEFT_BRACKET 0x5b 113 | #define UNIVERSAL_BACKSLASH 0x5c 114 | #define UNIVERSAL_RIGHT_BRACKET 0x5d 115 | 116 | // #define UNIVERSAL_ 0x5e 117 | // #define UNIVERSAL_ 0x5f 118 | 119 | #define UNIVERSAL_ENTER 0x60 120 | #define UNIVERSAL_RETURN 0x60 121 | 122 | #define UNIVERSAL_ESCAPE 0x61 123 | #define UNIVERSAL_TAB 0x62 124 | #define UNIVERSAL_BACKSPACE 0x63 125 | #define UNIVERSAL_CAPS_LOCK 0x64 126 | #define UNIVERSAL_NUM_LOCK 0x65 127 | 128 | // #define UNIVERSAL_ 0x66 129 | 130 | #define UNIVERSAL_UNICODE 0x67 131 | 132 | // #define UNIVERSAL_ 0x68 133 | // #define UNIVERSAL_ 0x69 134 | // #define UNIVERSAL_ 0x6a 135 | // #define UNIVERSAL_ 0x6b 136 | // #define UNIVERSAL_ 0x6c 137 | // #define UNIVERSAL_ 0x6d 138 | // #define UNIVERSAL_ 0x6e 139 | // #define UNIVERSAL_ 0x6f 140 | 141 | #define UNIVERSAL_SHIFT 0x70 142 | 143 | #define UNIVERSAL_RIGHT_SHIFT 0x71 144 | 145 | #define UNIVERSAL_CONTROL 0x72 146 | 147 | #define UNIVERSAL_RIGHT_CONTROL 0x73 148 | 149 | #define UNIVERSAL_MENU 0x74 150 | #define UNIVERSAL_ALT 0x74 151 | #define UNIVERSAL_OPTION 0x74 152 | #define UNIVERSAL_ALTGR 0x75 153 | 154 | #define UNIVERSAL_RIGHT_OPTION 0x75 155 | 156 | #define UNIVERSAL_COMMAND 0x76 157 | 158 | // #define UNIVERSAL_ 0x77 159 | // #define UNIVERSAL_ 0x78 160 | // #define UNIVERSAL_ 0x79 161 | // #define UNIVERSAL_ 0x7a 162 | // #define UNIVERSAL_ 0x7b 163 | // #define UNIVERSAL_ 0x7c 164 | // #define UNIVERSAL_ 0x7d 165 | // #define UNIVERSAL_ 0x7e 166 | // #define UNIVERSAL_ 0x7f 167 | 168 | #define UNIVERSAL_MOUSE_UP 0x80 169 | #define UNIVERSAL_MOUSE_UP_RIGHT 0x81 170 | #define UNIVERSAL_MOUSE_RIGHT 0x82 171 | #define UNIVERSAL_MOUSE_DOWN_RIGHT 0x83 172 | #define UNIVERSAL_MOUSE_DOWN 0x84 173 | #define UNIVERSAL_MOUSE_DOWN_LEFT 0x85 174 | #define UNIVERSAL_MOUSE_LEFT 0x86 175 | #define UNIVERSAL_MOUSE_UP_LEFT 0x87 176 | #define UNIVERSAL_MOUSE_BUTTON_CLICK 0x88 177 | #define UNIVERSAL_MOUSE_BUTTON_DOUBLECLICK 0x89 178 | #define UNIVERSAL_MOUSE_BUTTON_DOWN 0x8a 179 | #define UNIVERSAL_MOUSE_BUTTON_UP 0x8b 180 | #define UNIVERSAL_MOUSE_ON_CODE 0x8c 181 | #define UNIVERSAL_MOUSE_OFF_CODE 0x8d 182 | #define UNIVERSAL_MOUSE_BUTTON_TOGGLE 0x8e 183 | 184 | // commandeered by fred for the right mouse button 185 | #define UNIVERSAL_MOUSE_RBUTTON_CLICK 0x8f 186 | #define UNIVERSAL_MOUSE_RBUTTON_DOUBLECLICK 0x90 187 | #define UNIVERSAL_MOUSE_RBUTTON_DOWN 0x91 188 | #define UNIVERSAL_MOUSE_RBUTTON_UP 0x92 189 | #define UNIVERSAL_MOUSE_RBUTTON_TOGGLE 0x93 190 | 191 | // commandeered by fred for the middle mouse button 192 | #define UNIVERSAL_MOUSE_MBUTTON_CLICK 0x94 193 | #define UNIVERSAL_MOUSE_MBUTTON_DOUBLECLICK 0x95 194 | #define UNIVERSAL_MOUSE_MBUTTON_DOWN 0x96 195 | #define UNIVERSAL_MOUSE_MBUTTON_UP 0x97 196 | #define UNIVERSAL_MOUSE_MBUTTON_TOGGLE 0x98 197 | 198 | // commandeered by fred for the mouse button 4 199 | #define UNIVERSAL_MOUSE_BUTTON4_CLICK 0x99 200 | #define UNIVERSAL_MOUSE_BUTTON4_DOUBLECLICK 0x9a 201 | #define UNIVERSAL_MOUSE_BUTTON4_DOWN 0x9b 202 | #define UNIVERSAL_MOUSE_BUTTON4_UP 0x9c 203 | #define UNIVERSAL_MOUSE_BUTTON4_TOGGLE 0x9d 204 | 205 | // commandeered by fred for the mouse button 5 206 | #define UNIVERSAL_MOUSE_BUTTON5_CLICK 0x9e 207 | #define UNIVERSAL_MOUSE_BUTTON5_DOUBLECLICK 0x9f 208 | #define UNIVERSAL_MOUSE_BUTTON5_DOWN 0xa0 209 | #define UNIVERSAL_MOUSE_BUTTON5_UP 0xa1 210 | #define UNIVERSAL_MOUSE_BUTTON5_TOGGLE 0xa2 211 | 212 | // commandeered by fred for the mouse button 6 213 | #define UNIVERSAL_MOUSE_BUTTON6_CLICK 0xa3 214 | #define UNIVERSAL_MOUSE_BUTTON6_DOUBLECLICK 0xa4 215 | #define UNIVERSAL_MOUSE_BUTTON6_DOWN 0xa5 216 | #define UNIVERSAL_MOUSE_BUTTON6_UP 0xa6 217 | #define UNIVERSAL_MOUSE_BUTTON6_TOGGLE 0xa7 218 | 219 | // commandeered by fred for the mouse button 7 220 | #define UNIVERSAL_MOUSE_BUTTON7_CLICK 0xa8 221 | #define UNIVERSAL_MOUSE_BUTTON7_DOUBLECLICK 0xa9 222 | #define UNIVERSAL_MOUSE_BUTTON7_DOWN 0xaa 223 | #define UNIVERSAL_MOUSE_BUTTON7_UP 0xab 224 | #define UNIVERSAL_MOUSE_BUTTON7_TOGGLE 0xac 225 | 226 | // commandeered by fred for the mouse button 8 227 | #define UNIVERSAL_MOUSE_BUTTON8_CLICK 0xad 228 | #define UNIVERSAL_MOUSE_BUTTON8_DOUBLECLICK 0xae 229 | #define UNIVERSAL_MOUSE_BUTTON8_DOWN 0xaf 230 | #define UNIVERSAL_MOUSE_BUTTON8_UP 0xb0 231 | #define UNIVERSAL_MOUSE_BUTTON8_TOGGLE 0xb1 232 | 233 | // commandeered by fred for Wait 234 | #define UNIVERSAL_WAIT 0xb2 235 | 236 | // #define UNIVERSAL_ 0xb3 237 | // #define UNIVERSAL_ 0xb4 238 | // #define UNIVERSAL_ 0xb5 239 | // #define UNIVERSAL_ 0xb6 240 | // #define UNIVERSAL_ 0xb7 241 | // #define UNIVERSAL_ 0xb8 242 | // #define UNIVERSAL_ 0xb9 243 | // #define UNIVERSAL_ 0xba 244 | // #define UNIVERSAL_ 0xbb 245 | // #define UNIVERSAL_ 0xbc 246 | // #define UNIVERSAL_ 0xbd 247 | // #define UNIVERSAL_ 0xbe 248 | // #define UNIVERSAL_ 0xbf 249 | 250 | #define UNIVERSAL_GOTO_LEVEL 0xc0 251 | 252 | #define UNIVERSAL_GOTO_LEVEL_1 0xc1 253 | #define UNIVERSAL_GOTO_LEVEL_2 0xc2 254 | #define UNIVERSAL_GOTO_LEVEL_3 0xc3 255 | #define UNIVERSAL_GOTO_LEVEL_4 0xc4 256 | #define UNIVERSAL_GOTO_LEVEL_5 0xc5 257 | #define UNIVERSAL_GOTO_LEVEL_6 0xc6 258 | #define UNIVERSAL_GOTO_LEVEL_7 0xc7 259 | #define UNIVERSAL_GOTO_LEVEL_8 0xc8 260 | #define UNIVERSAL_GOTO_LEVEL_9 0xc9 261 | #define UNIVERSAL_GOTO_LEVEL_10 0xca 262 | #define UNIVERSAL_GOTO_LEVEL_11 0xcb 263 | #define UNIVERSAL_GOTO_LEVEL_12 0xcc 264 | #define UNIVERSAL_GOTO_LEVEL_13 0xcd 265 | #define UNIVERSAL_GOTO_LEVEL_14 0xce 266 | #define UNIVERSAL_GOTO_LEVEL_15 0xcf 267 | 268 | #define UNIVERSAL_NON_REPEATING 0xd0 269 | #define UNIVERSAL_SEPARATE_REPEAT_KEY 0xd1 270 | #define UNIVERSAL_NON_SMART_TYPING 0xd2 271 | 272 | // #define UNIVERSAL_ 0xd3 273 | // #define UNIVERSAL_ 0xd4 274 | // #define UNIVERSAL_ 0xd5 275 | // #define UNIVERSAL_ 0xd6 276 | // #define UNIVERSAL_ 0xd7 277 | // #define UNIVERSAL_ 0xd8 278 | // #define UNIVERSAL_ 0xd9 279 | // #define UNIVERSAL_ 0xda 280 | // #define UNIVERSAL_ 0xdb 281 | // #define UNIVERSAL_ 0xdc 282 | // #define UNIVERSAL_ 0xdd 283 | // #define UNIVERSAL_ 0xde 284 | // #define UNIVERSAL_ 0xdf 285 | 286 | #define UNIVERSAL_SETUP1 0xe0 287 | #define UNIVERSAL_SETUP2 0xe1 288 | 289 | // these are sub-codes for setup functions 290 | 291 | #define UNIVERSAL_SETUP1_RESPONSE_RATE 0x41 // plus rate 292 | #define UNIVERSAL_SETUP1_LIFT_OFF_ON 0x42 293 | #define UNIVERSAL_SETUP1_LIFT_OFF_OFF 0x43 294 | #define UNIVERSAL_SETUP1_REPEAT_LATCHING_ON 0x4A 295 | #define UNIVERSAL_SETUP1_REPEAT_LATCHING_OFF 0x4B 296 | #define UNIVERSAL_SETUP1_SHIFT_NO_LATCHING 0x4E 297 | #define UNIVERSAL_SETUP1_3LIGHTS 0x51 298 | #define UNIVERSAL_SETUP1_6LIGHTS 0x52 299 | #define UNIVERSAL_SETUP1_MOUSE_SPEED 0x55 // plus speed 300 | #define UNIVERSAL_SETUP1_CUSTOM_OVERLAY_LEVEL 0x58 // plus level 301 | #define UNIVERSAL_SETUP1_DATA_SEND_RATE 0x32 // plus rate 302 | #define UNIVERSAL_SETUP1_REPEAT_RATE 0x49 // plus rate 303 | #define UNIVERSAL_SETUP1_KEYSOUND_ON 0x45 304 | #define UNIVERSAL_SETUP1_KEYSOUND_OFF 0x44 305 | #define UNIVERSAL_SETUP1_SHIFT_LATCHING 0x4C 306 | #define UNIVERSAL_SETUP1_LIST_FEATURES 0x33 307 | #define UNIVERSAL_SETUP1_SHIFT_LOCKING 0x4D 308 | #define UNIVERSAL_SETUP1_MOUSE_ARROWS_ON 0x56 309 | #define UNIVERSAL_SETUP1_MOUSE_ARROWS_OFF 0x57 310 | #define UNIVERSAL_SETUP1_SMART_TYPING_ON 0x53 311 | #define UNIVERSAL_SETUP1_SMART_TYPING_OFF 0x54 312 | #define UNIVERSAL_SETUP1_REPEAT_ON 0x47 313 | #define UNIVERSAL_SETUP1_REPEAT_OFF 0x48 314 | #define UNIVERSAL_SETUP1_LIST_FEATURES 0x33 315 | 316 | #define UNIVERSAL_SETUP2_FEATURE_RESET 0x45 317 | 318 | // #define UNIVERSAL_ 0xe2 319 | // #define UNIVERSAL_ 0xe3 320 | // #define UNIVERSAL_ 0xe4 321 | // #define UNIVERSAL_ 0xe5 322 | // #define UNIVERSAL_ 0xe6 323 | // #define UNIVERSAL_ 0xe7 324 | // #define UNIVERSAL_ 0xe8 325 | // #define UNIVERSAL_ 0xe9 326 | // #define UNIVERSAL_ 0xea 327 | // #define UNIVERSAL_ 0xeb 328 | // #define UNIVERSAL_ 0xec 329 | // #define UNIVERSAL_ 0xed 330 | // #define UNIVERSAL_ 0xee 331 | // #define UNIVERSAL_ 0xef 332 | // #define UNIVERSAL_ 0xf0 333 | // #define UNIVERSAL_ 0xf1 334 | // #define UNIVERSAL_ 0xf2 335 | // #define UNIVERSAL_ 0xf3 336 | // #define UNIVERSAL_ 0xf4 337 | // #define UNIVERSAL_ 0xf5 338 | // #define UNIVERSAL_ 0xf6 339 | // #define UNIVERSAL_ 0xf7 340 | // #define UNIVERSAL_ 0xf8 341 | // #define UNIVERSAL_ 0xf9 342 | // #define UNIVERSAL_ 0xfa 343 | // #define UNIVERSAL_ 0xfb 344 | // #define UNIVERSAL_ 0xfc 345 | // #define UNIVERSAL_ 0xfd 346 | // #define UNIVERSAL_ 0xfe 347 | // #define UNIVERSAL_ 0xff 348 | -------------------------------------------------------------------------------- /src/ik_firmware.h: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2023 Ha Thach (tinyusb.org) for Adafruit Industries 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | // from https://github.com/ATMakersOrg/OpenIKeys/blob/master/original/IntelliKeys/WindowsOld/Win/Loading%20Driver/EzLoader_Firmware.c 26 | static const INTEL_HEX_RECORD ik_firmware[] = { 27 | 16, 28 | 0x1865, 29 | 0, 30 | {0x01,0x22,0x00,0x01,0x2a,0x01,0x01,0x33,0x01,0xc1,0x01,0xc1,0x82,0x02,0x23,0x00}, 31 | 1, 32 | 0x1875, 33 | 0, 34 | {0x00}, 35 | 16, 36 | 0x800, 37 | 0, 38 | {0xc2,0xac,0x43,0x34,0x40,0x90,0x7f,0x9d,0x74,0xff,0xf0,0x90,0x7f,0x97,0xe5,0x34}, 39 | 16, 40 | 0x810, 41 | 0, 42 | {0xf0,0x90,0x7f,0x98,0xe0,0x54,0xdf,0xf0,0xe0,0x44,0x20,0xf0,0xe4,0x90,0x7f,0x9d}, 43 | 16, 44 | 0x820, 45 | 0, 46 | {0xf0,0x22,0xe5,0x10,0x25,0xe0,0x24,0x14,0xf5,0x82,0xe4,0x34,0x22,0xf5,0x83,0xe0}, 47 | 16, 48 | 0x830, 49 | 0, 50 | {0xfe,0xa3,0xe0,0xff,0xe5,0x0f,0x25,0xe0,0x24,0x00,0xf5,0x82,0xe4,0x34,0x20,0xf5}, 51 | 16, 52 | 0x840, 53 | 0, 54 | {0x83,0x22,0x90,0x7f,0x9d,0x74,0xff,0xf0,0x90,0x7f,0x97,0xe5,0x11,0xf0,0x90,0x7f}, 55 | 16, 56 | 0x850, 57 | 0, 58 | {0x98,0xe0,0x22,0xe5,0x23,0x90,0x7e,0x85,0xf0,0xa3,0xe5,0x24,0xf0,0xc2,0x05,0x90}, 59 | 16, 60 | 0x860, 61 | 0, 62 | {0x7f,0xb7,0x74,0x08,0xf0,0x22,0x90,0x7f,0x9d,0x74,0xff,0xf0,0xe4,0x90,0x7f,0x97}, 63 | 16, 64 | 0x870, 65 | 0, 66 | {0xf0,0x90,0x7f,0x98,0xe0,0x22,0x90,0x7f,0x98,0xe0,0x54,0x7f,0xf0,0xe0,0x44,0xe0}, 67 | 16, 68 | 0x880, 69 | 0, 70 | {0xf0,0xe0,0x22,0x75,0xf0,0x05,0xef,0x12,0x06,0xc2,0xee,0x75,0xf0,0x05,0xa4,0x25}, 71 | 16, 72 | 0x890, 73 | 0, 74 | {0x83,0xf5,0x83,0x22,0x90,0x7d,0xc2,0xe0,0xfe,0x90,0x7d,0xc1,0xe0,0x7c,0x00,0x24}, 75 | 16, 76 | 0x8a0, 77 | 0, 78 | {0x00,0xff,0xec,0x3e,0xfe,0x22,0xe4,0xf5,0x2b,0xf5,0x2c,0xf5,0x35,0xf5,0x36,0x22}, 79 | 16, 80 | 0x8b0, 81 | 0, 82 | {0xe5,0x13,0xfa,0xe5,0x0f,0x75,0xf0,0x08,0xa4,0x24,0x00,0xff,0xe5,0xf0,0x3a,0xfe}, 83 | 16, 84 | 0x8c0, 85 | 0, 86 | {0xed,0x7a,0x00,0x2f,0x22,0x74,0xff,0xf0,0x90,0x7f,0x97,0xe5,0x43,0xf0,0x90,0x7f}, 87 | 16, 88 | 0x8d0, 89 | 0, 90 | {0x98,0xe0,0x54,0xfe,0xf0,0xe0,0x44,0x01,0x22,0xaf,0x3a,0xae,0x39,0xad,0x38,0xac}, 91 | 16, 92 | 0x8e0, 93 | 0, 94 | {0x37,0x22,0x90,0x7f,0x9a,0xe0,0xf5,0x12,0x90,0x7f,0x98,0xe0,0x44,0xe0,0xf0,0x22}, 95 | 16, 96 | 0x8f0, 97 | 0, 98 | {0xaf,0x0d,0x74,0xc1,0x2f,0xf5,0x82,0xe4,0x34,0x7d,0xf5,0x83,0xe0,0xfe,0x22,0x54}, 99 | 16, 100 | 0x900, 101 | 0, 102 | {0x1f,0xf0,0xe0,0x44,0xe0,0x22,0x54,0x3f,0xf0,0xe0,0x44,0xe0,0x22,0x54,0x5f,0xf0}, 103 | 16, 104 | 0x910, 105 | 0, 106 | {0xe0,0x44,0xe0,0x22,0xab,0x3a,0xaa,0x39,0xa9,0x38,0xa8,0x37,0xc3,0x02,0x06,0xb1}, 107 | 16, 108 | 0x920, 109 | 0, 110 | {0x25,0xe0,0x24,0x14,0xf5,0x82,0xe4,0x34,0x22,0xf5,0x83,0x22,0xe5,0x12,0xc3,0x13}, 111 | 16, 112 | 0x930, 113 | 0, 114 | {0xf5,0x12,0x0c,0xec,0x64,0x08,0x22,0xe5,0x11,0x25,0xe0,0x44,0x01,0xf5,0x11,0x0d}, 115 | 16, 116 | 0x940, 117 | 0, 118 | {0xed,0x22,0xe5,0x2c,0x24,0x01,0xff,0xe4,0x35,0x2b,0xfe,0xef,0x22,0x90,0x7f,0x98}, 119 | 16, 120 | 0x950, 121 | 0, 122 | {0xe0,0x54,0x9f,0x22,0x90,0x7f,0x98,0xe0,0x54,0xbf,0x22,0xe5,0x10,0x75,0xf0,0x08}, 123 | 5, 124 | 0x960, 125 | 0, 126 | {0xa4,0x2c,0xf5,0x13,0x22}, 127 | 16, 128 | 0x1328, 129 | 0, 130 | {0x90,0x7f,0xa1,0xe0,0x44,0x01,0xf0,0xe4,0x90,0x7f,0x93,0xf0,0x90,0x7f,0x94,0xf0}, 131 | 16, 132 | 0x1338, 133 | 0, 134 | {0x90,0x7f,0x95,0x74,0x02,0xf0,0x90,0x7f,0x9c,0x74,0x10,0xf0,0xe4,0x90,0x7f,0x9d}, 135 | 16, 136 | 0x1348, 137 | 0, 138 | {0xf0,0x90,0x7f,0x9e,0x74,0xf3,0xf0,0x90,0x7f,0x96,0x74,0x10,0xf0,0x90,0x7f,0x98}, 139 | 16, 140 | 0x1358, 141 | 0, 142 | {0x74,0xe1,0xf0,0x75,0x89,0x20,0x75,0x8d,0xcc,0xd2,0x8e,0x75,0x98,0x40,0xc2,0xac}, 143 | 16, 144 | 0x1368, 145 | 0, 146 | {0x53,0x8e,0xdf,0x75,0xcb,0xb1,0x75,0xca,0xdf,0x75,0xc8,0x04,0xd2,0xad,0x12,0x18}, 147 | 14, 148 | 0x1378, 149 | 0, 150 | {0x95,0x90,0x7f,0x98,0xe0,0x44,0x10,0xf0,0x12,0x17,0x4a,0x02,0x13,0x86}, 151 | 16, 152 | 0x1386, 153 | 0, 154 | {0xc2,0x06,0xd2,0x00,0xc2,0xac,0x75,0x34,0xcf,0x12,0x08,0x05,0x75,0x43,0x03,0x12}, 155 | 16, 156 | 0x1396, 157 | 0, 158 | {0x08,0xc5,0x12,0x08,0x1b,0x74,0xff,0xf0,0x12,0x08,0x6d,0x12,0x08,0xff,0x12,0x08}, 159 | 16, 160 | 0x13a6, 161 | 0, 162 | {0x1b,0x74,0xff,0xf0,0x12,0x08,0x6d,0x12,0x09,0x06,0x12,0x08,0x1b,0x74,0xff,0xf0}, 163 | 16, 164 | 0x13b6, 165 | 0, 166 | {0x12,0x08,0x6d,0x12,0x09,0x0d,0x12,0x08,0x1b,0x12,0x08,0xa7,0xf5,0x3a,0xf5,0x39}, 167 | 16, 168 | 0x13c6, 169 | 0, 170 | {0xf5,0x38,0xf5,0x37,0xd2,0x0b,0x12,0x10,0x00,0xe4,0xff,0xfe,0x7e,0x08,0x90,0x7d}, 171 | 12, 172 | 0x13d6, 173 | 0, 174 | {0x80,0xe4,0xf0,0xa3,0xde,0xfc,0x90,0x7f,0xbb,0x74,0x08,0xf0}, 175 | 1, 176 | 0x13e2, 177 | 0, 178 | {0x22}, 179 | 16, 180 | 0xc0b, 181 | 0, 182 | {0xe5,0x22,0x60,0x03,0x12,0x09,0x65,0xc2,0x08,0xc2,0x09,0xc2,0x0a,0xc3,0xe5,0x3a}, 183 | 16, 184 | 0xc1b, 185 | 0, 186 | {0x95,0x42,0xff,0xe5,0x39,0x95,0x41,0xfe,0xe5,0x38,0x95,0x40,0xfd,0xe5,0x37,0x95}, 187 | 16, 188 | 0xc2b, 189 | 0, 190 | {0x3f,0xfc,0xe4,0x7b,0x01,0xfa,0xf9,0xf8,0xd3,0x12,0x06,0xb1,0x50,0x02,0xd2,0x08}, 191 | 16, 192 | 0xc3b, 193 | 0, 194 | {0xaf,0x3e,0xae,0x3d,0xad,0x3c,0xac,0x3b,0x12,0x09,0x14,0x60,0x02,0xd2,0x09,0xc3}, 195 | 16, 196 | 0xc4b, 197 | 0, 198 | {0xe5,0x3a,0x95,0x47,0xff,0xe5,0x39,0x95,0x46,0xfe,0xe5,0x38,0x95,0x45,0xfd,0xe5}, 199 | 16, 200 | 0xc5b, 201 | 0, 202 | {0x37,0x95,0x44,0xfc,0xe4,0x7b,0x0a,0xfa,0xf9,0xf8,0xd3,0x12,0x06,0xb1,0x50,0x02}, 203 | 16, 204 | 0xc6b, 205 | 0, 206 | {0xd2,0x0a,0x30,0x08,0x13,0xe4,0xf5,0x31,0xf5,0x32,0x12,0x08,0xd9,0x8f,0x42,0x8e}, 207 | 16, 208 | 0xc7b, 209 | 0, 210 | {0x41,0x8d,0x40,0x8c,0x3f,0x12,0x0d,0x54,0x30,0x06,0x14,0x30,0x00,0x11,0x30,0x09}, 211 | 16, 212 | 0xc8b, 213 | 0, 214 | {0x0e,0x12,0x08,0xd9,0x8f,0x3e,0x8e,0x3d,0x8d,0x3c,0x8c,0x3b,0x12,0x14,0xa9,0x30}, 215 | 16, 216 | 0xc9b, 217 | 0, 218 | {0x06,0x13,0x30,0x0a,0x10,0x12,0x08,0xd9,0x8f,0x47,0x8e,0x46,0x8d,0x45,0x8c,0x44}, 219 | 16, 220 | 0xcab, 221 | 0, 222 | {0xc2,0x0b,0x12,0x10,0x00,0x30,0xac,0x10,0xaf,0x28,0xae,0x27,0xad,0x26,0xac,0x25}, 223 | 16, 224 | 0xcbb, 225 | 0, 226 | {0x12,0x09,0x14,0x40,0x03,0x12,0x08,0x00,0x20,0x05,0x02,0xa1,0x53,0xc2,0x07,0x30}, 227 | 16, 228 | 0xccb, 229 | 0, 230 | {0x01,0x25,0xc2,0x01,0xe5,0x36,0x65,0x2c,0x70,0x04,0xe5,0x35,0x65,0x2b,0x60,0x04}, 231 | 16, 232 | 0xcdb, 233 | 0, 234 | {0xd2,0x07,0x80,0x25,0x90,0x7e,0x80,0x74,0x33,0xf0,0x05,0x24,0xe5,0x24,0x70,0x02}, 235 | 16, 236 | 0xceb, 237 | 0, 238 | {0x05,0x23,0x12,0x08,0x53,0x80,0x12,0xe5,0x33,0x70,0x0e,0xe5,0x36,0x65,0x2c,0x70}, 239 | 16, 240 | 0xcfb, 241 | 0, 242 | {0x04,0xe5,0x35,0x65,0x2b,0x60,0x02,0xd2,0x07,0x30,0x07,0x4c,0xae,0x35,0xaf,0x36}, 243 | 16, 244 | 0xd0b, 245 | 0, 246 | {0x7c,0x00,0x7d,0x05,0x12,0x06,0x9f,0x74,0x20,0x2f,0xf9,0x74,0x20,0x3e,0xfa,0x7b}, 247 | 16, 248 | 0xd1b, 249 | 0, 250 | {0x01,0xc0,0x02,0xc0,0x01,0x7a,0x7e,0x79,0x80,0x78,0x80,0x7c,0x7e,0x7d,0x01,0xd0}, 251 | 16, 252 | 0xd2b, 253 | 0, 254 | {0x01,0xd0,0x02,0x7e,0x00,0x7f,0x05,0x12,0x06,0x11,0x05,0x36,0xe5,0x36,0x70,0x02}, 255 | 16, 256 | 0xd3b, 257 | 0, 258 | {0x05,0x35,0xae,0x35,0x64,0x64,0x4e,0x70,0x04,0xf5,0x35,0xf5,0x36,0x05,0x24,0xe5}, 259 | 8, 260 | 0xd4b, 261 | 0, 262 | {0x24,0x70,0x02,0x05,0x23,0x12,0x08,0x53}, 263 | 1, 264 | 0xd53, 265 | 0, 266 | {0x22}, 267 | 16, 268 | 0x1800, 269 | 0, 270 | {0x30,0x00,0x09,0xe4,0xfb,0x7d,0x01,0x7f,0x3a,0x02,0x12,0x4f,0xe4,0xfb,0xfd,0x7f}, 271 | 5, 272 | 0x1810, 273 | 0, 274 | {0x3a,0x12,0x12,0x4f,0x22}, 275 | 16, 276 | 0xf8e, 277 | 0, 278 | {0x30,0x00,0x5b,0xe5,0x36,0x65,0x2c,0x70,0x04,0xe5,0x35,0x65,0x2b,0x70,0x4f,0xe4}, 279 | 16, 280 | 0xf9e, 281 | 0, 282 | {0xf5,0x0e,0xe5,0x0e,0xc3,0x95,0x30,0x50,0x1c,0xe5,0x0e,0x12,0x08,0x36,0xe0,0xfc}, 283 | 16, 284 | 0xfae, 285 | 0, 286 | {0xa3,0xe0,0xfd,0xec,0xf5,0x10,0xed,0xf5,0x0f,0xfb,0xad,0x10,0x7f,0x3e,0x12,0x12}, 287 | 16, 288 | 0xfbe, 289 | 0, 290 | {0x4f,0x05,0x0e,0x80,0xdd,0x90,0x7f,0x9b,0xe0,0x20,0xe3,0x09,0x7b,0x01,0x7d,0x01}, 291 | 16, 292 | 0xfce, 293 | 0, 294 | {0x7f,0x3f,0x12,0x12,0x4f,0x90,0x7f,0x9b,0xe0,0x20,0xe2,0x09,0x7b,0x01,0x7d,0x02}, 295 | 14, 296 | 0xfde, 297 | 0, 298 | {0x7f,0x3f,0x12,0x12,0x4f,0x7b,0x01,0x7d,0x02,0x7f,0x40,0x12,0x12,0x4f}, 299 | 1, 300 | 0xfec, 301 | 0, 302 | {0x22}, 303 | 16, 304 | 0x965, 305 | 0, 306 | {0x90,0x7d,0xc0,0xe0,0x14,0xb4,0x16,0x00,0x40,0x02,0x41,0xb5,0x90,0x09,0x77,0x25}, 307 | 16, 308 | 0x975, 309 | 0, 310 | {0xe0,0x73,0x41,0x12,0x21,0xc3,0x21,0xf6,0x21,0xbe,0x21,0xb5,0x41,0x05,0x41,0x1d}, 311 | 16, 312 | 0x985, 313 | 0, 314 | {0x41,0x27,0x21,0xb9,0x41,0x2c,0x41,0x22,0x41,0x31,0x41,0xb5,0x41,0xb5,0x21,0xd0}, 315 | 16, 316 | 0x995, 317 | 0, 318 | {0x21,0xaa,0x21,0xae,0x21,0xa3,0x41,0xb5,0x41,0xb5,0x41,0x3d,0x41,0x6c,0xd2,0x0b}, 319 | 16, 320 | 0x9a5, 321 | 0, 322 | {0x12,0x10,0x00,0x41,0xb5,0xd2,0x02,0x41,0xb5,0x12,0x08,0xa6,0xc2,0x02,0x41,0xb5}, 323 | 16, 324 | 0x9b5, 325 | 0, 326 | {0xd2,0x01,0x41,0xb5,0x12,0x18,0x00,0x41,0xb5,0x12,0x12,0xc9,0x41,0xb5,0x90,0x7d}, 327 | 16, 328 | 0x9c5, 329 | 0, 330 | {0xc1,0xe0,0xff,0xa3,0xe0,0xfd,0x12,0x11,0xc9,0x41,0xb5,0xe4,0xf5,0x0c,0xf5,0x0d}, 331 | 16, 332 | 0x9d5, 333 | 0, 334 | {0xe5,0x0d,0x04,0xff,0x90,0x7d,0xc1,0xe0,0xfd,0x12,0x11,0xc9,0x05,0x0d,0xe5,0x0d}, 335 | 16, 336 | 0x9e5, 337 | 0, 338 | {0x70,0x02,0x05,0x0c,0xc3,0x94,0x09,0xe5,0x0c,0x64,0x80,0x94,0x80,0x40,0xe1,0x41}, 339 | 16, 340 | 0x9f5, 341 | 0, 342 | {0xb5,0x90,0x7d,0xc1,0xe0,0x60,0x05,0x12,0x15,0xd4,0x41,0xb5,0xc2,0x06,0x41,0xb5}, 343 | 16, 344 | 0xa05, 345 | 0, 346 | {0xd2,0x02,0x12,0x13,0x86,0x90,0x7d,0xc1,0xe0,0xf5,0x33,0x41,0xb5,0xe4,0xfb,0x7d}, 347 | 16, 348 | 0xa15, 349 | 0, 350 | {0x02,0x7f,0x38,0x12,0x12,0x4f,0x41,0xb5,0x12,0x16,0xf8,0x41,0xb5,0x12,0x16,0x6b}, 351 | 16, 352 | 0xa25, 353 | 0, 354 | {0x41,0xb5,0x12,0x17,0x91,0x41,0xb5,0x12,0x0f,0x8e,0x41,0xb5,0x12,0x08,0xa6,0xc2}, 355 | 16, 356 | 0xa35, 357 | 0, 358 | {0x02,0xd2,0x0b,0x12,0x14,0x58,0x41,0xb5,0xe4,0xf5,0x0c,0xf5,0x0d,0x12,0x08,0xf0}, 359 | 16, 360 | 0xa45, 361 | 0, 362 | {0x74,0x80,0x2f,0xf5,0x82,0xe4,0x34,0x7d,0xf5,0x83,0xee,0xf0,0x05,0x0d,0xe5,0x0d}, 363 | 16, 364 | 0xa55, 365 | 0, 366 | {0x70,0x02,0x05,0x0c,0x64,0x07,0x45,0x0c,0x70,0xe3,0xe4,0x90,0x7d,0x87,0xf0,0x90}, 367 | 16, 368 | 0xa65, 369 | 0, 370 | {0x7f,0xbb,0x74,0x08,0xf0,0x80,0x49,0xe4,0xf5,0x0c,0xf5,0x0d,0x12,0x08,0xf0,0x74}, 371 | 16, 372 | 0xa75, 373 | 0, 374 | {0x00,0x2f,0xf5,0x82,0xe4,0x34,0x7d,0xf5,0x83,0xee,0xf0,0x05,0x0d,0xe5,0x0d,0x70}, 375 | 16, 376 | 0xa85, 377 | 0, 378 | {0x02,0x05,0x0c,0x64,0x03,0x45,0x0c,0x70,0xe3,0x75,0x0c,0x00,0x75,0x0d,0x03,0x74}, 379 | 16, 380 | 0xa95, 381 | 0, 382 | {0x00,0x25,0x0d,0xf5,0x82,0xe4,0x34,0x7d,0xf5,0x83,0xe4,0xf0,0x05,0x0d,0xe5,0x0d}, 383 | 16, 384 | 0xaa5, 385 | 0, 386 | {0x70,0x02,0x05,0x0c,0x64,0x08,0x45,0x0c,0x70,0xe5,0x90,0x7f,0xbd,0x74,0x03,0xf0}, 387 | 7, 388 | 0xab5, 389 | 0, 390 | {0xe4,0xf5,0x22,0x90,0x7f,0xc9,0xf0}, 391 | 1, 392 | 0xabc, 393 | 0, 394 | {0x22}, 395 | 16, 396 | 0x15d4, 397 | 0, 398 | {0xe4,0xf5,0x29,0xf5,0x30,0xc2,0x03,0xc2,0x04,0xf5,0x42,0xf5,0x41,0xf5,0x40,0xf5}, 399 | 16, 400 | 0x15e4, 401 | 0, 402 | {0x3f,0xf5,0x3e,0xf5,0x3d,0xf5,0x3c,0xf5,0x3b,0xf5,0x47,0xf5,0x46,0xf5,0x45,0xf5}, 403 | 16, 404 | 0x15f4, 405 | 0, 406 | {0x44,0xff,0x7f,0x03,0x78,0x2d,0xe4,0xf6,0x08,0xdf,0xfc,0x12,0x08,0xa6,0xd2,0x06}, 407 | 3, 408 | 0x1604, 409 | 0, 410 | {0x02,0x18,0x00}, 411 | 2, 412 | 0x11c9, 413 | 0, 414 | {0xa9,0x05}, 415 | 16, 416 | 0x11cb, 417 | 0, 418 | {0xef,0x64,0x01,0x70,0x0e,0xe9,0x60,0x05,0x53,0x34,0x7f,0x80,0x03,0x43,0x34,0x80}, 419 | 16, 420 | 0x11db, 421 | 0, 422 | {0x02,0x08,0x05,0xef,0x24,0xfe,0xb4,0x08,0x00,0x50,0x34,0x90,0x11,0xec,0x25,0xe0}, 423 | 16, 424 | 0x11eb, 425 | 0, 426 | {0x73,0x21,0xfc,0x41,0x00,0x41,0x04,0x41,0x08,0x41,0x0c,0x41,0x10,0x41,0x14,0x41}, 427 | 16, 428 | 0x11fb, 429 | 0, 430 | {0x18,0x7e,0x40,0x80,0x1a,0x7e,0x80,0x80,0x16,0x7e,0x01,0x80,0x12,0x7e,0x10,0x80}, 431 | 16, 432 | 0x120b, 433 | 0, 434 | {0x0e,0x7e,0x20,0x80,0x0a,0x7e,0x02,0x80,0x06,0x7e,0x04,0x80,0x02,0x7e,0x08,0xe9}, 435 | 16, 436 | 0x121b, 437 | 0, 438 | {0x60,0x15,0xef,0x64,0x04,0x60,0x03,0xbf,0x07,0x08,0x63,0x06,0xff,0xee,0x52,0x43}, 439 | 16, 440 | 0x122b, 441 | 0, 442 | {0x80,0x18,0xee,0x42,0x43,0x80,0x13,0xef,0x64,0x04,0x60,0x03,0xbf,0x07,0x05,0xee}, 443 | 16, 444 | 0x123b, 445 | 0, 446 | {0x42,0x43,0x80,0x06,0x63,0x06,0xff,0xee,0x52,0x43,0x90,0x7f,0x9d,0x12,0x08,0xc5}, 447 | 3, 448 | 0x124b, 449 | 0, 450 | {0x12,0x08,0x1b}, 451 | 1, 452 | 0x124e, 453 | 0, 454 | {0x22}, 455 | 3, 456 | 0x20, 457 | 0, 458 | {0x02,0x08,0x00}, 459 | 16, 460 | 0x12c9, 461 | 0, 462 | {0x90,0x7d,0xc2,0xe0,0x60,0x55,0x90,0x7d,0xc1,0xe0,0xf5,0x8d,0x53,0x34,0x8f,0xa3}, 463 | 16, 464 | 0x12d9, 465 | 0, 466 | {0xe0,0x24,0xfe,0x60,0x0c,0x14,0x60,0x0e,0x24,0x02,0x70,0x0d,0x43,0x34,0x30,0x80}, 467 | 16, 468 | 0x12e9, 469 | 0, 470 | {0x08,0x43,0x34,0x20,0x80,0x03,0x43,0x34,0x10,0x12,0x08,0x05,0x90,0x7d,0xc3,0xe0}, 471 | 16, 472 | 0x12f9, 473 | 0, 474 | {0x60,0x19,0xe0,0xff,0xe4,0xef,0x25,0x3a,0xf5,0x28,0xe4,0x35,0x39,0xf5,0x27,0xe4}, 475 | 16, 476 | 0x1309, 477 | 0, 478 | {0x35,0x38,0xf5,0x26,0xe4,0x35,0x37,0xf5,0x25,0x80,0x0a,0x74,0xff,0xf5,0x28,0xf5}, 479 | 15, 480 | 0x1319, 481 | 0, 482 | {0x27,0xf5,0x26,0xf5,0x25,0xd2,0xac,0x75,0x99,0x55,0x22,0x12,0x00,0x20,0x22}, 483 | 3, 484 | 0x23, 485 | 0, 486 | {0x02,0x18,0x9d}, 487 | 7, 488 | 0x189d, 489 | 0, 490 | {0x53,0x98,0xfd,0x75,0x99,0x55,0x32}, 491 | 3, 492 | 0x2b, 493 | 0, 494 | {0x02,0x16,0x07}, 495 | 16, 496 | 0x1607, 497 | 0, 498 | {0xc0,0xe0,0xc0,0xd0,0x75,0xd0,0x00,0xc0,0x04,0xc0,0x05,0xc0,0x06,0xc0,0x07,0xc2}, 499 | 16, 500 | 0x1617, 501 | 0, 502 | {0xcf,0x12,0x08,0xd9,0xef,0x24,0x01,0xf5,0x3a,0xe4,0x3e,0xf5,0x39,0xe4,0x3d,0xf5}, 503 | 16, 504 | 0x1627, 505 | 0, 506 | {0x38,0xe4,0x3c,0xf5,0x37,0xd0,0x07,0xd0,0x06,0xd0,0x05,0xd0,0x04,0xd0,0xd0,0xd0}, 507 | 2, 508 | 0x1637, 509 | 0, 510 | {0xe0,0x32}, 511 | 2, 512 | 0x3, 513 | 0, 514 | {0xaa,0x06}, 515 | 16, 516 | 0x5, 517 | 0, 518 | {0xea,0x90,0x22,0x54,0xf0,0xef,0xa3,0xf0,0xa3,0xed,0xf0,0x7a,0x22,0x7b,0x54,0x7d}, 519 | 11, 520 | 0x15, 521 | 0, 522 | {0x03,0x7f,0x51,0x12,0x17,0x5b,0x7f,0x51,0x02,0x15,0x35}, 523 | 10, 524 | 0x156b, 525 | 0, 526 | {0x8e,0x0e,0x8f,0x0f,0x8d,0x10,0x8a,0x11,0x8b,0x12}, 527 | 16, 528 | 0x1575, 529 | 0, 530 | {0xe4,0xf5,0x13,0xe5,0x13,0xc3,0x95,0x10,0x50,0x20,0x05,0x0f,0xe5,0x0f,0xae,0x0e}, 531 | 16, 532 | 0x1585, 533 | 0, 534 | {0x70,0x02,0x05,0x0e,0x14,0xff,0xe5,0x12,0x25,0x13,0xf5,0x82,0xe4,0x35,0x11,0xf5}, 535 | 10, 536 | 0x1595, 537 | 0, 538 | {0x83,0xe0,0xfd,0x12,0x00,0x03,0x05,0x13,0x80,0xd9}, 539 | 1, 540 | 0x159f, 541 | 0, 542 | {0x22}, 543 | 10, 544 | 0x7d7, 545 | 0, 546 | {0x8e,0x0e,0x8f,0x0f,0x8d,0x10,0x8a,0x11,0x8b,0x12}, 547 | 16, 548 | 0x7e1, 549 | 0, 550 | {0xe5,0x0e,0x90,0x22,0x54,0xf0,0xef,0xa3,0xf0,0x7a,0x22,0x7b,0x54,0x7d,0x02,0x7f}, 551 | 15, 552 | 0x7f1, 553 | 0, 554 | {0x51,0x12,0x17,0x5b,0xab,0x12,0xaa,0x11,0xad,0x10,0x7f,0x51,0x02,0x13,0xe3}, 555 | 16, 556 | 0xd54, 557 | 0, 558 | {0xe4,0xf5,0x30,0xf5,0x0c,0xe5,0x0c,0x14,0x60,0x18,0x14,0x60,0x26,0x24,0x02,0x70}, 559 | 16, 560 | 0xd64, 561 | 0, 562 | {0x31,0x12,0x08,0x66,0x12,0x08,0xff,0x12,0x08,0x1b,0x53,0x34,0xf4,0x12,0x08,0x08}, 563 | 16, 564 | 0xd74, 565 | 0, 566 | {0x80,0x20,0x12,0x08,0x66,0x12,0x09,0x06,0x12,0x08,0x1b,0x53,0x34,0xf5,0x12,0x08}, 567 | 16, 568 | 0xd84, 569 | 0, 570 | {0x08,0x80,0x0f,0x12,0x08,0x66,0x12,0x09,0x0d,0x12,0x08,0x1b,0x53,0x34,0xf6,0x12}, 571 | 16, 572 | 0xd94, 573 | 0, 574 | {0x08,0x08,0xe4,0xf5,0x0d,0xe5,0x0d,0x14,0x60,0x0f,0x14,0x60,0x17,0x24,0x02,0x70}, 575 | 16, 576 | 0xda4, 577 | 0, 578 | {0x1c,0x12,0x08,0x76,0x54,0x7f,0xf0,0x80,0x14,0x12,0x09,0x4d,0x12,0x08,0x7c,0x54}, 579 | 16, 580 | 0xdb4, 581 | 0, 582 | {0x9f,0xf0,0x80,0x09,0x12,0x09,0x54,0x12,0x08,0x7c,0x54,0xbf,0xf0,0x90,0x7f,0x9a}, 583 | 16, 584 | 0xdc4, 585 | 0, 586 | {0xe0,0xff,0x12,0x08,0xe8,0xef,0xf4,0x60,0x07,0xad,0x0d,0xaf,0x0c,0x12,0x03,0x75}, 587 | 16, 588 | 0xdd4, 589 | 0, 590 | {0x05,0x0d,0xe5,0x0d,0xc3,0x94,0x03,0x40,0xbc,0x43,0x34,0x0f,0x12,0x08,0x05,0x05}, 591 | 16, 592 | 0xde4, 593 | 0, 594 | {0x0c,0xe5,0x0c,0xc3,0x94,0x03,0x50,0x02,0xa1,0x59,0xe4,0xfd,0xfc,0xec,0xc3,0x95}, 595 | 16, 596 | 0xdf4, 597 | 0, 598 | {0x30,0x50,0x16,0xec,0x12,0x08,0x36,0xe0,0xff,0xec,0x12,0x08,0x36,0xe0,0xa3,0xe0}, 599 | 16, 600 | 0xe04, 601 | 0, 602 | {0xf5,0x0e,0xef,0x70,0x01,0x0d,0x0c,0x80,0xe4,0xed,0xc3,0x94,0x08,0x40,0x0f,0x30}, 603 | 16, 604 | 0xe14, 605 | 0, 606 | {0x00,0x08,0xe4,0xfb,0xfd,0x7f,0x3a,0x12,0x12,0x4f,0xc2,0x00,0x80,0x11,0x20,0x00}, 607 | 16, 608 | 0xe24, 609 | 0, 610 | {0x0c,0x12,0x15,0xd4,0xe4,0xfb,0x7d,0x01,0x7f,0x3a,0x12,0x12,0x4f,0xd2,0x00,0x30}, 611 | 8, 612 | 0xe34, 613 | 0, 614 | {0x06,0x06,0x30,0x00,0x03,0x12,0x0e,0x3d}, 615 | 1, 616 | 0xe3c, 617 | 0, 618 | {0x22}, 619 | 4, 620 | 0x375, 621 | 0, 622 | {0x8f,0x0f,0x8d,0x10}, 623 | 16, 624 | 0x379, 625 | 0, 626 | {0x75,0x11,0xfe,0xe4,0xfd,0xe5,0x0f,0x14,0x60,0x12,0x14,0x60,0x1a,0x24,0x02,0x70}, 627 | 16, 628 | 0x389, 629 | 0, 630 | {0x1f,0x12,0x08,0x42,0x12,0x08,0xff,0x12,0x08,0x1b,0x80,0x14,0x12,0x08,0x42,0x12}, 631 | 16, 632 | 0x399, 633 | 0, 634 | {0x09,0x06,0x12,0x08,0x1b,0x80,0x09,0x12,0x08,0x42,0x12,0x09,0x0d,0x12,0x08,0x1b}, 635 | 16, 636 | 0x3a9, 637 | 0, 638 | {0xe5,0x10,0x14,0x60,0x0f,0x14,0x60,0x17,0x24,0x02,0x70,0x1c,0x12,0x08,0x76,0x54}, 639 | 16, 640 | 0x3b9, 641 | 0, 642 | {0x7f,0xf0,0x80,0x14,0x12,0x09,0x4d,0x12,0x08,0x7c,0x54,0x9f,0xf0,0x80,0x09,0x12}, 643 | 16, 644 | 0x3c9, 645 | 0, 646 | {0x09,0x54,0x12,0x08,0x7c,0x54,0xbf,0xf0,0x12,0x08,0xe2,0xe5,0x12,0xf4,0x60,0x4c}, 647 | 16, 648 | 0x3d9, 649 | 0, 650 | {0xe4,0xfc,0xe5,0x12,0x20,0xe0,0x40,0xe5,0x30,0xc3,0x94,0x10,0x50,0x39,0xe5,0x10}, 651 | 16, 652 | 0x3e9, 653 | 0, 654 | {0x60,0x09,0xb4,0x01,0x0b,0xec,0xc3,0x94,0x04,0x50,0x05,0x12,0x09,0x5b,0x80,0x13}, 655 | 16, 656 | 0x3f9, 657 | 0, 658 | {0xe5,0x10,0xb4,0x01,0x08,0xc3,0x74,0x1b,0x9c,0xf5,0x13,0x80,0x06,0xc3,0x74,0x13}, 659 | 16, 660 | 0x409, 661 | 0, 662 | {0x9c,0xf5,0x13,0x12,0x08,0xb0,0xff,0xea,0x3e,0xfe,0xab,0x30,0x05,0x30,0xeb,0x12}, 663 | 16, 664 | 0x419, 665 | 0, 666 | {0x08,0x36,0xee,0xf0,0xa3,0xef,0xf0,0x12,0x09,0x2c,0x70,0xb6,0x12,0x09,0x37,0x64}, 667 | 16, 668 | 0x429, 669 | 0, 670 | {0x08,0x60,0x02,0x61,0x7e,0x75,0x11,0xfc,0xe4,0xfd,0xe5,0x0f,0x14,0x60,0x12,0x14}, 671 | 16, 672 | 0x439, 673 | 0, 674 | {0x60,0x1a,0x24,0x02,0x70,0x1f,0x12,0x08,0x42,0x12,0x08,0xff,0x12,0x08,0x1b,0x80}, 675 | 16, 676 | 0x449, 677 | 0, 678 | {0x14,0x12,0x08,0x42,0x12,0x09,0x06,0x12,0x08,0x1b,0x80,0x09,0x12,0x08,0x42,0x12}, 679 | 16, 680 | 0x459, 681 | 0, 682 | {0x09,0x0d,0x12,0x08,0x1b,0xe5,0x10,0x14,0x60,0x0f,0x14,0x60,0x17,0x24,0x02,0x70}, 683 | 16, 684 | 0x469, 685 | 0, 686 | {0x1c,0x12,0x08,0x76,0x54,0x7f,0xf0,0x80,0x14,0x12,0x09,0x4d,0x12,0x08,0x7c,0x54}, 687 | 16, 688 | 0x479, 689 | 0, 690 | {0x9f,0xf0,0x80,0x09,0x12,0x09,0x54,0x12,0x08,0x7c,0x54,0xbf,0xf0,0x12,0x08,0xe2}, 691 | 16, 692 | 0x489, 693 | 0, 694 | {0xe5,0x12,0xf4,0x70,0x02,0xa1,0x37,0xe4,0xfc,0xe5,0x12,0x30,0xe0,0x02,0xa1,0x30}, 695 | 16, 696 | 0x499, 697 | 0, 698 | {0xe5,0x10,0x60,0x09,0xb4,0x01,0x0b,0xec,0xc3,0x94,0x04,0x50,0x05,0x12,0x09,0x5b}, 699 | 16, 700 | 0x4a9, 701 | 0, 702 | {0x80,0x13,0xe5,0x10,0xb4,0x01,0x08,0xc3,0x74,0x1b,0x9c,0xf5,0x13,0x80,0x06,0xc3}, 703 | 16, 704 | 0x4b9, 705 | 0, 706 | {0x74,0x13,0x9c,0xf5,0x13,0x12,0x08,0xb0,0xf5,0x15,0xea,0x3e,0xf5,0x14,0xe4,0xf9}, 707 | 16, 708 | 0x4c9, 709 | 0, 710 | {0xe9,0xc3,0x95,0x30,0x50,0x26,0xe9,0x12,0x08,0x36,0xe0,0xfe,0xa3,0xe0,0xff,0x65}, 711 | 16, 712 | 0x4d9, 713 | 0, 714 | {0x15,0x70,0x03,0xee,0x65,0x14,0x60,0x14,0xe5,0x15,0x24,0x01,0xfb,0xe4,0x35,0x14}, 715 | 16, 716 | 0x4e9, 717 | 0, 718 | {0xfa,0xef,0x6b,0x70,0x02,0xee,0x6a,0x60,0x03,0x09,0x80,0xd4,0xe9,0x65,0x30,0x70}, 719 | 16, 720 | 0x4f9, 721 | 0, 722 | {0x36,0xe5,0x30,0x24,0x02,0xff,0xe4,0x33,0xfe,0xd3,0xef,0x94,0x10,0xee,0x64,0x80}, 723 | 16, 724 | 0x509, 725 | 0, 726 | {0x94,0x80,0x50,0x23,0xaf,0x30,0x05,0x30,0xef,0x12,0x08,0x36,0xe5,0x14,0xf0,0xa3}, 727 | 16, 728 | 0x519, 729 | 0, 730 | {0xe5,0x15,0xf0,0x24,0x01,0xff,0xe4,0x35,0x14,0xfe,0xab,0x30,0x05,0x30,0xeb,0x12}, 731 | 16, 732 | 0x529, 733 | 0, 734 | {0x08,0x36,0xee,0xf0,0xa3,0xef,0xf0,0x12,0x09,0x2c,0x60,0x02,0x81,0x92,0x12,0x09}, 735 | 7, 736 | 0x539, 737 | 0, 738 | {0x37,0x64,0x07,0x60,0x02,0x81,0x33}, 739 | 1, 740 | 0x540, 741 | 0, 742 | {0x22}, 743 | 16, 744 | 0xe3d, 745 | 0, 746 | {0xe4,0xf5,0x0f,0xe5,0x0f,0xc3,0x95,0x30,0x50,0x38,0xe4,0xf5,0x11,0xf5,0x10,0xe5}, 747 | 16, 748 | 0xe4d, 749 | 0, 750 | {0x10,0xc3,0x95,0x29,0x50,0x15,0x12,0x08,0x22,0xe0,0xfc,0xa3,0xe0,0xb5,0x07,0x07}, 751 | 16, 752 | 0xe5d, 753 | 0, 754 | {0xec,0xb5,0x06,0x03,0x75,0x11,0x01,0x05,0x10,0x80,0xe4,0xe5,0x11,0x70,0x0f,0x12}, 755 | 16, 756 | 0xe6d, 757 | 0, 758 | {0x08,0x34,0xe0,0xfa,0xa3,0xe0,0xfb,0xea,0xfd,0x7f,0x34,0x12,0x12,0x4f,0x05,0x0f}, 759 | 16, 760 | 0xe7d, 761 | 0, 762 | {0x80,0xc1,0xe4,0xf5,0x10,0xe5,0x10,0xc3,0x95,0x29,0x50,0x3a,0xe4,0xf5,0x11,0xf5}, 763 | 16, 764 | 0xe8d, 765 | 0, 766 | {0x0f,0xe5,0x0f,0xc3,0x95,0x30,0x50,0x15,0x12,0x08,0x22,0xe0,0xfc,0xa3,0xe0,0xb5}, 767 | 16, 768 | 0xe9d, 769 | 0, 770 | {0x07,0x07,0xec,0xb5,0x06,0x03,0x75,0x11,0x01,0x05,0x0f,0x80,0xe4,0xe5,0x11,0x70}, 771 | 16, 772 | 0xead, 773 | 0, 774 | {0x11,0xe5,0x10,0x12,0x09,0x20,0xe0,0xfa,0xa3,0xe0,0xfb,0xea,0xfd,0x7f,0x35,0x12}, 775 | 16, 776 | 0xebd, 777 | 0, 778 | {0x12,0x4f,0x05,0x10,0x80,0xbf,0xe4,0xf5,0x0f,0xe5,0x0f,0xc3,0x95,0x30,0x50,0x16}, 779 | 16, 780 | 0xecd, 781 | 0, 782 | {0x12,0x08,0x34,0xe0,0xfe,0xa3,0xe0,0xff,0xe5,0x0f,0x12,0x09,0x20,0xee,0xf0,0xa3}, 783 | 9, 784 | 0xedd, 785 | 0, 786 | {0xef,0xf0,0x05,0x0f,0x80,0xe3,0x85,0x30,0x29}, 787 | 1, 788 | 0xee6, 789 | 0, 790 | {0x22}, 791 | 16, 792 | 0x124f, 793 | 0, 794 | {0xac,0x07,0x30,0x02,0x74,0x12,0x09,0x42,0x65,0x36,0x70,0x03,0xee,0x65,0x35,0x60}, 795 | 16, 796 | 0x125f, 797 | 0, 798 | {0x68,0x12,0x09,0x42,0x64,0x64,0x4e,0x70,0x06,0xe5,0x36,0x45,0x35,0x60,0x5a,0xae}, 799 | 16, 800 | 0x126f, 801 | 0, 802 | {0x2b,0xaf,0x2c,0x90,0x20,0x20,0x12,0x08,0x83,0xec,0xf0,0xae,0x2b,0xaf,0x2c,0x90}, 803 | 16, 804 | 0x127f, 805 | 0, 806 | {0x20,0x21,0x12,0x08,0x83,0xed,0xf0,0xae,0x2b,0xaf,0x2c,0x90,0x20,0x22,0x12,0x08}, 807 | 16, 808 | 0x128f, 809 | 0, 810 | {0x83,0xeb,0xf0,0xae,0x39,0xaf,0x3a,0xac,0x2b,0xad,0x2c,0x90,0x20,0x23,0x75,0xf0}, 811 | 16, 812 | 0x129f, 813 | 0, 814 | {0x05,0xed,0x12,0x06,0xc2,0xec,0x12,0x08,0x8b,0xee,0xf0,0xa3,0xef,0xf0,0x05,0x2c}, 815 | 16, 816 | 0x12af, 817 | 0, 818 | {0xe5,0x2c,0x70,0x02,0x05,0x2b,0xae,0x2b,0x64,0x64,0x4e,0x70,0x04,0xf5,0x2b,0xf5}, 819 | 10, 820 | 0x12bf, 821 | 0, 822 | {0x2c,0x05,0x32,0xe5,0x32,0x70,0x02,0x05,0x31,0x22}, 823 | 16, 824 | 0x14a9, 825 | 0, 826 | {0x90,0x7f,0x9b,0xe0,0x30,0xe3,0x04,0xc2,0x0b,0x80,0x02,0xd2,0x0b,0xa2,0x03,0x30}, 827 | 16, 828 | 0x14b9, 829 | 0, 830 | {0x0b,0x01,0xb3,0x50,0x10,0xa2,0x0b,0xe4,0x33,0xfb,0x7d,0x01,0x7f,0x36,0x12,0x12}, 831 | 16, 832 | 0x14c9, 833 | 0, 834 | {0x4f,0xa2,0x0b,0x92,0x03,0x90,0x7f,0x9b,0xe0,0x30,0xe2,0x04,0xc2,0x0b,0x80,0x02}, 835 | 16, 836 | 0x14d9, 837 | 0, 838 | {0xd2,0x0b,0xa2,0x04,0x30,0x0b,0x01,0xb3,0x50,0x10,0xa2,0x0b,0xe4,0x33,0xfb,0x7d}, 839 | 10, 840 | 0x14e9, 841 | 0, 842 | {0x02,0x7f,0x36,0x12,0x12,0x4f,0xa2,0x0b,0x92,0x04}, 843 | 1, 844 | 0x14f3, 845 | 0, 846 | {0x22}, 847 | 16, 848 | 0x1000, 849 | 0, 850 | {0xe4,0xfa,0xea,0x44,0xf0,0x52,0x34,0x12,0x08,0x05,0x74,0x03,0xf0,0x90,0x7f,0x97}, 851 | 16, 852 | 0x1010, 853 | 0, 854 | {0xe0,0x54,0xfc,0xf0,0x90,0x7f,0x96,0xe0,0x54,0xef,0xf0,0xaf,0x02,0xe4,0xf9,0xfe}, 855 | 16, 856 | 0x1020, 857 | 0, 858 | {0xe9,0x25,0xe0,0xf9,0x90,0x7f,0x9a,0xe0,0x30,0xe2,0x03,0x43,0x01,0x01,0xef,0x30}, 859 | 16, 860 | 0x1030, 861 | 0, 862 | {0xe3,0x09,0x90,0x7f,0x97,0xe0,0x44,0x02,0xf0,0x80,0x07,0x90,0x7f,0x97,0xe0,0x54}, 863 | 16, 864 | 0x1040, 865 | 0, 866 | {0xfd,0xf0,0xef,0x25,0xe0,0xff,0x90,0x7f,0x97,0xe0,0x44,0x01,0xf0,0xe0,0x54,0xfe}, 867 | 16, 868 | 0x1050, 869 | 0, 870 | {0xf0,0x0e,0xbe,0x08,0xcb,0xea,0x60,0x2b,0x24,0x2c,0xf8,0xe6,0xff,0xd3,0x99,0x40}, 871 | 16, 872 | 0x1060, 873 | 0, 874 | {0x05,0xef,0x99,0xfe,0x80,0x04,0xc3,0xe9,0x9f,0xfe,0xee,0xc3,0x95,0x2a,0x50,0x03}, 875 | 16, 876 | 0x1070, 877 | 0, 878 | {0x30,0x0b,0x10,0xea,0x14,0xfd,0xab,0x01,0x7f,0x37,0x12,0x12,0x4f,0x74,0x2c,0x2a}, 879 | 16, 880 | 0x1080, 881 | 0, 882 | {0xf8,0xa6,0x01,0x90,0x7f,0x99,0xe0,0x30,0xe5,0xf9,0x90,0x7f,0x96,0xe0,0x44,0x10}, 883 | 16, 884 | 0x1090, 885 | 0, 886 | {0x12,0x08,0x1b,0x43,0x34,0x0f,0x12,0x08,0x08,0x0a,0xea,0x64,0x04,0x60,0x02,0x01}, 887 | 1, 888 | 0x10a0, 889 | 0, 890 | {0x02}, 891 | 1, 892 | 0x10a1, 893 | 0, 894 | {0x22}, 895 | 16, 896 | 0x166b, 897 | 0, 898 | {0x30,0x05,0x2d,0x12,0x08,0x94,0x90,0x7e,0x80,0x74,0x41,0xf0,0x7a,0x7e,0x7b,0x81}, 899 | 16, 900 | 0x167b, 901 | 0, 902 | {0x7d,0x01,0x12,0x07,0xd7,0x90,0x7d,0xc1,0xe0,0x90,0x7e,0x82,0xf0,0x90,0x7d,0xc2}, 903 | 16, 904 | 0x168b, 905 | 0, 906 | {0xe0,0x90,0x7e,0x83,0xf0,0x05,0x24,0xe5,0x24,0x70,0x02,0x05,0x23,0x12,0x08,0x53}, 907 | 1, 908 | 0x169b, 909 | 0, 910 | {0x22}, 911 | 16, 912 | 0x16f8, 913 | 0, 914 | {0x30,0x05,0x1d,0x12,0x08,0x94,0x90,0x7e,0x80,0x74,0x39,0xf0,0x7a,0x7e,0x7b,0x81}, 915 | 16, 916 | 0x1708, 917 | 0, 918 | {0x7d,0x07,0x12,0x07,0xd7,0x05,0x24,0xe5,0x24,0x70,0x02,0x05,0x23,0x12,0x08,0x53}, 919 | 1, 920 | 0x1718, 921 | 0, 922 | {0x22}, 923 | 16, 924 | 0x1791, 925 | 0, 926 | {0x12,0x08,0x94,0xd3,0xef,0x94,0x06,0xee,0x94,0x00,0x40,0x0c,0x90,0x7d,0xc3,0xe0}, 927 | 8, 928 | 0x17a1, 929 | 0, 930 | {0xfd,0x7a,0x7d,0x7b,0xc4,0x12,0x15,0x6b}, 931 | 1, 932 | 0x17a9, 933 | 0, 934 | {0x22}, 935 | 16, 936 | 0x10a2, 937 | 0, 938 | {0x90,0x7f,0xec,0xe0,0xf4,0x54,0x80,0xff,0xc4,0x54,0x0f,0xff,0xe0,0x54,0x07,0x2f}, 939 | 16, 940 | 0x10b2, 941 | 0, 942 | {0x25,0xe0,0x24,0xb4,0xf5,0x82,0xe4,0x34,0x7f,0xf5,0x83,0x22,0x90,0x7f,0xb4,0xe0}, 943 | 16, 944 | 0x10c2, 945 | 0, 946 | {0x44,0x01,0xf0,0x22,0xff,0x74,0x00,0x25,0x12,0xf5,0x82,0xe4,0x34,0x7f,0xf5,0x83}, 947 | 16, 948 | 0x10d2, 949 | 0, 950 | {0xef,0xf0,0xe5,0x12,0x24,0x01,0xf5,0x12,0xe4,0x35,0x11,0xf5,0x11,0xe4,0x35,0x10}, 951 | 16, 952 | 0x10e2, 953 | 0, 954 | {0xf5,0x10,0xe4,0x35,0x0f,0xf5,0x0f,0x22,0x90,0x7f,0x00,0xf0,0xe4,0xa3,0xf0,0x90}, 955 | 16, 956 | 0x10f2, 957 | 0, 958 | {0x7f,0xb5,0x74,0x02,0xf0,0x22,0x90,0x7f,0xec,0xe0,0x25,0xe0,0x24,0xb9,0xf5,0x82}, 959 | 16, 960 | 0x1102, 961 | 0, 962 | {0xe4,0x34,0x0b,0xf5,0x83,0xe4,0x93,0x22,0xe4,0xfc,0xfd,0xfe,0xab,0x12,0xaa,0x11}, 963 | 16, 964 | 0x1112, 965 | 0, 966 | {0xa9,0x10,0xa8,0x0f,0xc3,0x02,0x06,0xb1,0xaa,0x06,0xa9,0x07,0x7b,0x01,0x8b,0x0c}, 967 | 16, 968 | 0x1122, 969 | 0, 970 | {0x8a,0x0d,0x89,0x0e,0xea,0x49,0x22,0xe4,0xf5,0x0b,0xf5,0x0a,0xf5,0x09,0xf5,0x08}, 971 | 11, 972 | 0x1132, 973 | 0, 974 | {0x22,0xe4,0xf5,0x12,0xf5,0x11,0xf5,0x10,0xf5,0x0f,0x22}, 975 | 16, 976 | 0xee7, 977 | 0, 978 | {0x12,0x11,0x29,0x7f,0xe8,0x7e,0x03,0x12,0x17,0xdb,0xc2,0x0f,0xc2,0x0c,0xc2,0x0e}, 979 | 16, 980 | 0xef7, 981 | 0, 982 | {0xc2,0x0d,0x12,0x13,0x28,0x75,0x4b,0x0a,0x75,0x4c,0xbd,0x75,0x4f,0x0a,0x75,0x50}, 983 | 16, 984 | 0xf07, 985 | 0, 986 | {0xcf,0x75,0x52,0x0b,0x75,0x53,0xbf,0xd2,0xe8,0x43,0xd8,0x20,0x90,0x7f,0xaf,0xe0}, 987 | 16, 988 | 0xf17, 989 | 0, 990 | {0x44,0x01,0xf0,0x90,0x7f,0xae,0xe0,0x44,0x1d,0xf0,0xd2,0xaf,0x20,0x0d,0x3b,0x20}, 991 | 16, 992 | 0xf27, 993 | 0, 994 | {0x0d,0x05,0xd2,0x0b,0x12,0x14,0x58,0x12,0x11,0x29,0x7f,0x40,0x7e,0x92,0x7d,0x04}, 995 | 16, 996 | 0xf37, 997 | 0, 998 | {0x7c,0x00,0xab,0x0b,0xaa,0x0a,0xa9,0x09,0xa8,0x08,0xc3,0x12,0x06,0xb1,0x50,0xdc}, 999 | 16, 1000 | 0xf47, 1001 | 0, 1002 | {0x20,0x0d,0xd9,0xe5,0x0b,0x24,0x01,0xf5,0x0b,0xe4,0x35,0x0a,0xf5,0x0a,0xe4,0x35}, 1003 | 16, 1004 | 0xf57, 1005 | 0, 1006 | {0x09,0xf5,0x09,0xe4,0x35,0x08,0xf5,0x08,0x80,0xd0,0x53,0x8e,0xf8,0x30,0x0d,0x05}, 1007 | 16, 1008 | 0xf67, 1009 | 0, 1010 | {0x12,0x00,0x4e,0xc2,0x0d,0x30,0x0f,0x1a,0x12,0x16,0x9c,0x50,0x15,0xc2,0x0f,0x12}, 1011 | 16, 1012 | 0xf77, 1013 | 0, 1014 | {0x17,0x3a,0x20,0x0c,0x07,0x90,0x7f,0xd6,0xe0,0x20,0xe7,0xf3,0x12,0x17,0x77,0x12}, 1015 | 7, 1016 | 0xf87, 1017 | 0, 1018 | {0x00,0x36,0x12,0x0c,0x0b,0x80,0xd6}, 1019 | 16, 1020 | 0x4e, 1021 | 0, 1022 | {0x90,0x7f,0xe8,0xe0,0x64,0x21,0x70,0x5e,0xa3,0xe0,0x24,0xf7,0x70,0x4d,0xe4,0x90}, 1023 | 16, 1024 | 0x5e, 1025 | 0, 1026 | {0x7f,0xc5,0xf0,0x90,0x7f,0xaa,0xe0,0x30,0xe0,0xf9,0x90,0x7f,0xec,0xe0,0x70,0x27}, 1027 | 16, 1028 | 0x6e, 1029 | 0, 1030 | {0xff,0x74,0xc0,0x2f,0xf5,0x82,0xe4,0x34,0x7e,0xf5,0x83,0xe0,0xfe,0x74,0xc0,0x2f}, 1031 | 16, 1032 | 0x7e, 1033 | 0, 1034 | {0xf5,0x82,0xe4,0x34,0x7d,0xf5,0x83,0xee,0xf0,0x0f,0xbf,0x08,0xe4,0x90,0x7f,0xaa}, 1035 | 16, 1036 | 0x8e, 1037 | 0, 1038 | {0x74,0x01,0xf0,0xf5,0x22,0x80,0x17,0x90,0x7f,0xec,0xe0,0xb4,0x01,0x08,0x90,0x7e}, 1039 | 16, 1040 | 0x9e, 1041 | 0, 1042 | {0xc0,0xe0,0xf5,0x4a,0x80,0x08,0x12,0x10,0xbe,0x80,0x03,0x12,0x10,0xbe,0x90,0x7f}, 1043 | 16, 1044 | 0xae, 1045 | 0, 1046 | {0xb4,0xe0,0x44,0x02,0xf0,0x22,0x90,0x7f,0xe9,0xe0,0x70,0x02,0x41,0x9e,0x14,0x70}, 1047 | 16, 1048 | 0xbe, 1049 | 0, 1050 | {0x02,0x41,0xe0,0x24,0xfe,0x70,0x02,0x61,0x31,0x24,0xfb,0x70,0x02,0x41,0x99,0x14}, 1051 | 16, 1052 | 0xce, 1053 | 0, 1054 | {0x70,0x02,0x41,0x49,0x14,0x70,0x02,0x41,0x3f,0x14,0x70,0x02,0x41,0x44,0x24,0x05}, 1055 | 16, 1056 | 0xde, 1057 | 0, 1058 | {0x60,0x02,0x61,0x65,0x12,0x00,0x2e,0x40,0x02,0x61,0x6d,0x90,0x7f,0xeb,0xe0,0x24}, 1059 | 16, 1060 | 0xee, 1061 | 0, 1062 | {0xfe,0x60,0x22,0x14,0x60,0x3d,0x24,0xe2,0x70,0x02,0x41,0x27,0x14,0x70,0x02,0x21}, 1063 | 16, 1064 | 0xfe, 1065 | 0, 1066 | {0xc6,0x24,0x21,0x60,0x02,0x41,0x3a,0xe5,0x4b,0x90,0x7f,0xd4,0xf0,0xe5,0x4c,0x90}, 1067 | 16, 1068 | 0x10e, 1069 | 0, 1070 | {0x7f,0xd5,0xf0,0x61,0x6d,0x90,0x7f,0xea,0xe0,0xff,0x12,0x14,0xf4,0x12,0x11,0x1a}, 1071 | 16, 1072 | 0x11e, 1073 | 0, 1074 | {0x60,0x0c,0xee,0x90,0x7f,0xd4,0xf0,0xef,0x90,0x7f,0xd5,0xf0,0x61,0x6d,0x12,0x10}, 1075 | 16, 1076 | 0x12e, 1077 | 0, 1078 | {0xbe,0x61,0x6d,0x90,0x7f,0xea,0xe0,0xff,0x12,0x16,0xcc,0x12,0x11,0x1a,0x70,0x02}, 1079 | 2, 1080 | 0x13e, 1081 | 0, 1082 | {0x21,0xc1}, 1083 | 16, 1084 | 0x140, 1085 | 0, 1086 | {0xab,0x0c,0x8b,0x13,0x8a,0x14,0x89,0x15,0x12,0x06,0x37,0xf5,0x16,0x90,0x7f,0xee}, 1087 | 16, 1088 | 0x150, 1089 | 0, 1090 | {0xe0,0xff,0xe5,0x16,0xd3,0x9f,0x40,0x03,0xe0,0xf5,0x16,0xe5,0x16,0x60,0x55,0x12}, 1091 | 16, 1092 | 0x160, 1093 | 0, 1094 | {0x11,0x33,0xe5,0x16,0xc3,0x94,0x40,0x50,0x04,0xaf,0x16,0x80,0x02,0x7f,0x40,0x12}, 1095 | 16, 1096 | 0x170, 1097 | 0, 1098 | {0x11,0x0a,0x50,0x12,0xe5,0x15,0x25,0x12,0xf5,0x82,0xe5,0x14,0x35,0x11,0xf5,0x83}, 1099 | 16, 1100 | 0x180, 1101 | 0, 1102 | {0xe0,0x12,0x10,0xc6,0x80,0xdc,0xe5,0x16,0xc3,0x94,0x40,0x50,0x04,0xaf,0x16,0x80}, 1103 | 16, 1104 | 0x190, 1105 | 0, 1106 | {0x02,0x7f,0x40,0x90,0x7f,0xb5,0xef,0xf0,0xe5,0x16,0xc3,0x94,0x40,0x50,0x04,0xaf}, 1107 | 16, 1108 | 0x1a0, 1109 | 0, 1110 | {0x16,0x80,0x02,0x7f,0x40,0xc3,0xe5,0x16,0x9f,0xf5,0x16,0x90,0x7f,0xb4,0xe0,0x30}, 1111 | 15, 1112 | 0x1b0, 1113 | 0, 1114 | {0xe2,0xa9,0x80,0xf7,0xe4,0x90,0x7f,0xb5,0xf0,0x90,0x7f,0xb4,0x74,0x02,0xf0}, 1115 | 7, 1116 | 0x1bf, 1117 | 0, 1118 | {0x61,0x6d,0x12,0x10,0xbe,0x61,0x6d}, 1119 | 16, 1120 | 0x1c6, 1121 | 0, 1122 | {0x90,0x7f,0xec,0xe0,0x25,0xe0,0x24,0xb0,0xf5,0x82,0xe4,0x34,0x0b,0xf5,0x83,0xe4}, 1123 | 16, 1124 | 0x1d6, 1125 | 0, 1126 | {0x93,0xfe,0x74,0x01,0x93,0x8e,0x13,0xf5,0x14,0x90,0x7f,0xec,0xe0,0x90,0x0b,0xb6}, 1127 | 16, 1128 | 0x1e6, 1129 | 0, 1130 | {0x93,0xf5,0x51,0x90,0x7f,0xee,0xe0,0xff,0xe5,0x51,0xd3,0x9f,0x40,0x03,0xe0,0xf5}, 1131 | 16, 1132 | 0x1f6, 1133 | 0, 1134 | {0x51,0x12,0x11,0x33,0xaf,0x51,0x12,0x11,0x0a,0x50,0x15,0x85,0x14,0x82,0x85,0x13}, 1135 | 16, 1136 | 0x206, 1137 | 0, 1138 | {0x83,0xe4,0x93,0x12,0x10,0xc6,0x05,0x14,0xe5,0x14,0x70,0xe8,0x05,0x13,0x80,0xe4}, 1139 | 16, 1140 | 0x216, 1141 | 0, 1142 | {0x90,0x7f,0xb5,0xe5,0x51,0xf0,0x90,0x7f,0xb4,0xe0,0x20,0xe2,0x02,0x61,0x6d,0x80}, 1143 | 1, 1144 | 0x226, 1145 | 0, 1146 | {0xf5}, 1147 | 16, 1148 | 0x227, 1149 | 0, 1150 | {0x12,0x10,0xf8,0x90,0x7f,0xd4,0xf0,0x12,0x10,0xf8,0x74,0x01,0x93,0x90,0x7f,0xd5}, 1151 | 16, 1152 | 0x237, 1153 | 0, 1154 | {0xf0,0x61,0x6d,0x12,0x10,0xbe,0x61,0x6d,0x12,0x18,0x77,0x61,0x6d,0x12,0x18,0x8d}, 1155 | 16, 1156 | 0x247, 1157 | 0, 1158 | {0x61,0x6d,0x12,0x18,0x85,0x90,0x7f,0xea,0xe0,0x70,0x1e,0x90,0x7f,0xde,0xe0,0x54}, 1159 | 16, 1160 | 0x257, 1161 | 0, 1162 | {0xe5,0xf0,0x90,0x7f,0xdf,0xe0,0x54,0xf3,0xf0,0x90,0x7f,0xac,0xe0,0x54,0xfd,0xf0}, 1163 | 16, 1164 | 0x267, 1165 | 0, 1166 | {0x90,0x7f,0xad,0xe0,0x54,0xf3,0xf0,0x61,0x6d,0x90,0x7f,0xde,0xe0,0x44,0x1a,0xf0}, 1167 | 16, 1168 | 0x277, 1169 | 0, 1170 | {0x90,0x7f,0xdf,0xe0,0x44,0x0c,0xf0,0x90,0x7f,0xac,0xe0,0x44,0x02,0xf0,0x90,0x7f}, 1171 | 16, 1172 | 0x287, 1173 | 0, 1174 | {0xad,0xe0,0x44,0x0c,0xf0,0xe4,0x90,0x7f,0xc9,0xf0,0x90,0x7f,0xcb,0xf0,0xd2,0x05}, 1175 | 16, 1176 | 0x297, 1177 | 0, 1178 | {0x61,0x6d,0x12,0x17,0xf2,0x61,0x6d,0x12,0x00,0x30,0x40,0x02,0x61,0x6d,0x90,0x7f}, 1179 | 16, 1180 | 0x2a7, 1181 | 0, 1182 | {0xe8,0xe0,0x24,0x7f,0x60,0x19,0x14,0x60,0x20,0x24,0x02,0x70,0x27,0xa2,0x0c,0xe4}, 1183 | 16, 1184 | 0x2b7, 1185 | 0, 1186 | {0x33,0xff,0x25,0xe0,0xff,0xa2,0x0e,0xe4,0x33,0x4f,0x12,0x10,0xea,0x61,0x6d,0xe4}, 1187 | 16, 1188 | 0x2c7, 1189 | 0, 1190 | {0x90,0x7f,0x00,0xf0,0x12,0x10,0xef,0x61,0x6d,0x12,0x10,0xa2,0xe0,0x54,0x01,0x12}, 1191 | 16, 1192 | 0x2d7, 1193 | 0, 1194 | {0x10,0xea,0x61,0x6d,0x12,0x10,0xbe,0x61,0x6d,0x12,0x00,0x46,0x40,0x02,0x61,0x6d}, 1195 | 16, 1196 | 0x2e7, 1197 | 0, 1198 | {0x90,0x7f,0xe8,0xe0,0x24,0xfe,0x60,0x14,0x24,0x02,0x70,0x7a,0x90,0x7f,0xea,0xe0}, 1199 | 16, 1200 | 0x2f7, 1201 | 0, 1202 | {0xb4,0x01,0x04,0xc2,0x0c,0x61,0x6d,0x12,0x10,0xbe,0x61,0x6d,0x90,0x7f,0xea,0xe0}, 1203 | 16, 1204 | 0x307, 1205 | 0, 1206 | {0x70,0x23,0x12,0x10,0xa2,0xe4,0xf0,0x90,0x7f,0xec,0xe0,0x54,0x80,0xff,0x13,0x13}, 1207 | 12, 1208 | 0x317, 1209 | 0, 1210 | {0x13,0x54,0x1f,0xff,0xe0,0x54,0x07,0x2f,0x90,0x7f,0xd7,0xf0}, 1211 | 3, 1212 | 0x323, 1213 | 0, 1214 | {0xe4,0xf5,0x13}, 1215 | 16, 1216 | 0x326, 1217 | 0, 1218 | {0xe0,0x44,0x20,0xf0,0x80,0x41,0x12,0x10,0xbe,0x80,0x3c,0x12,0x00,0x48,0x50,0x37}, 1219 | 16, 1220 | 0x336, 1221 | 0, 1222 | {0x90,0x7f,0xe8,0xe0,0x24,0xfe,0x60,0x14,0x24,0x02,0x70,0x2b,0x90,0x7f,0xea,0xe0}, 1223 | 16, 1224 | 0x346, 1225 | 0, 1226 | {0xb4,0x01,0x04,0xd2,0x0c,0x80,0x20,0x12,0x10,0xbe,0x80,0x1b,0x90,0x7f,0xea,0xe0}, 1227 | 16, 1228 | 0x356, 1229 | 0, 1230 | {0x70,0x08,0x12,0x10,0xa2,0x74,0x01,0xf0,0x80,0x0d,0x12,0x10,0xbe,0x80,0x08,0x12}, 1231 | 14, 1232 | 0x366, 1233 | 0, 1234 | {0x18,0xab,0x50,0x03,0x12,0x10,0xbe,0x90,0x7f,0xb4,0xe0,0x44,0x02,0xf0}, 1235 | 1, 1236 | 0x374, 1237 | 0, 1238 | {0x22}, 1239 | 3, 1240 | 0x33, 1241 | 0, 1242 | {0x02,0x00,0x26}, 1243 | 4, 1244 | 0x26, 1245 | 0, 1246 | {0x53,0xd8,0xef,0x32}, 1247 | 7, 1248 | 0x18a4, 1249 | 0, 1250 | {0x53,0x91,0xef,0x90,0x7f,0xab,0x22}, 1251 | 16, 1252 | 0x169c, 1253 | 0, 1254 | {0x12,0x00,0x20,0xe4,0xf5,0x0c,0xf5,0x0d,0xe5,0x0d,0x04,0xff,0xe4,0xfd,0x12,0x11}, 1255 | 16, 1256 | 0x16ac, 1257 | 0, 1258 | {0xc9,0x05,0x0d,0xe5,0x0d,0x70,0x02,0x05,0x0c,0xc3,0x94,0x09,0xe5,0x0c,0x64,0x80}, 1259 | 15, 1260 | 0x16bc, 1261 | 0, 1262 | {0x94,0x80,0x40,0xe4,0x90,0x7f,0x98,0xe0,0x54,0xef,0xf0,0x12,0x17,0x4a,0xd3}, 1263 | 1, 1264 | 0x16cb, 1265 | 0, 1266 | {0x22}, 1267 | 12, 1268 | 0x36, 1269 | 0, 1270 | {0x90,0x7f,0x98,0xe0,0x44,0x10,0xf0,0x12,0x17,0x4a,0xd3,0x22}, 1271 | 2, 1272 | 0x2e, 1273 | 0, 1274 | {0xd3,0x22}, 1275 | 8, 1276 | 0x1885, 1277 | 0, 1278 | {0x90,0x7f,0xea,0xe0,0xf5,0x1b,0xd3,0x22}, 1279 | 14, 1280 | 0x17f2, 1281 | 0, 1282 | {0x90,0x7f,0x00,0xe5,0x1b,0xf0,0x90,0x7f,0xb5,0x74,0x01,0xf0,0xd3,0x22}, 1283 | 8, 1284 | 0x188d, 1285 | 0, 1286 | {0x90,0x7f,0xea,0xe0,0xf5,0x19,0xd3,0x22}, 1287 | 14, 1288 | 0x1877, 1289 | 0, 1290 | {0x90,0x7f,0x00,0xe5,0x19,0xf0,0x90,0x7f,0xb5,0x74,0x01,0xf0,0xd3,0x22}, 1291 | 2, 1292 | 0x30, 1293 | 0, 1294 | {0xd3,0x22}, 1295 | 2, 1296 | 0x46, 1297 | 0, 1298 | {0xd3,0x22}, 1299 | 2, 1300 | 0x48, 1301 | 0, 1302 | {0xd3,0x22}, 1303 | 2, 1304 | 0x18ab, 1305 | 0, 1306 | {0xd3,0x22}, 1307 | 16, 1308 | 0x1815, 1309 | 0, 1310 | {0xc0,0xe0,0xc0,0x83,0xc0,0x82,0xd2,0x0d,0x12,0x18,0xa4,0x74,0x01,0xf0,0xd0,0x82}, 1311 | 5, 1312 | 0x1825, 1313 | 0, 1314 | {0xd0,0x83,0xd0,0xe0,0x32}, 1315 | 16, 1316 | 0xfed, 1317 | 0, 1318 | {0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x12,0x18,0xa4,0x74,0x04,0xf0,0xd0,0x82,0xd0,0x83}, 1319 | 3, 1320 | 0xffd, 1321 | 0, 1322 | {0xd0,0xe0,0x32}, 1323 | 16, 1324 | 0x183f, 1325 | 0, 1326 | {0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x12,0x18,0xa4,0x74,0x02,0xf0,0xd0,0x82,0xd0,0x83}, 1327 | 3, 1328 | 0x184f, 1329 | 0, 1330 | {0xd0,0xe0,0x32}, 1331 | 16, 1332 | 0x1852, 1333 | 0, 1334 | {0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x12,0x18,0xa4,0x74,0x10,0xf0,0xd0,0x82,0xd0,0x83}, 1335 | 3, 1336 | 0x1862, 1337 | 0, 1338 | {0xd0,0xe0,0x32}, 1339 | 1, 1340 | 0x2a, 1341 | 0, 1342 | {0x32}, 1343 | 16, 1344 | 0x182a, 1345 | 0, 1346 | {0xc0,0xe0,0xc0,0x83,0xc0,0x82,0xd2,0x0f,0x12,0x18,0xa4,0x74,0x08,0xf0,0xd0,0x82}, 1347 | 5, 1348 | 0x183a, 1349 | 0, 1350 | {0xd0,0x83,0xd0,0xe0,0x32}, 1351 | 1, 1352 | 0x32, 1353 | 0, 1354 | {0x32}, 1355 | 1, 1356 | 0x42, 1357 | 0, 1358 | {0x32}, 1359 | 16, 1360 | 0x17c3, 1361 | 0, 1362 | {0xc0,0xe0,0xc0,0x83,0xc0,0x82,0xd2,0x05,0x53,0x91,0xef,0x90,0x7f,0xa9,0x74,0x02}, 1363 | 8, 1364 | 0x17d3, 1365 | 0, 1366 | {0xf0,0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32}, 1367 | 1, 1368 | 0x4a, 1369 | 0, 1370 | {0x32}, 1371 | 1, 1372 | 0x13ff, 1373 | 0, 1374 | {0x32}, 1375 | 16, 1376 | 0x17aa, 1377 | 0, 1378 | {0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x75,0x22,0x01,0x53,0x91,0xef,0x90,0x7f,0xaa,0x74}, 1379 | 9, 1380 | 0x17ba, 1381 | 0, 1382 | {0x04,0xf0,0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32}, 1383 | 1, 1384 | 0x18ad, 1385 | 0, 1386 | {0x32}, 1387 | 16, 1388 | 0x1719, 1389 | 0, 1390 | {0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x90,0x7d,0x40,0xe0,0xf5,0x4a,0x53,0x91,0xef,0x90}, 1391 | 16, 1392 | 0x1729, 1393 | 0, 1394 | {0x7f,0xaa,0x74,0x08,0xf0,0x90,0x7f,0xcb,0xe4,0xf0,0xd0,0x82,0xd0,0x83,0xd0,0xe0}, 1395 | 1, 1396 | 0x1739, 1397 | 0, 1398 | {0x32}, 1399 | 1, 1400 | 0x18ae, 1401 | 0, 1402 | {0x32}, 1403 | 1, 1404 | 0x18af, 1405 | 0, 1406 | {0x32}, 1407 | 1, 1408 | 0x18b0, 1409 | 0, 1410 | {0x32}, 1411 | 1, 1412 | 0x18b1, 1413 | 0, 1414 | {0x32}, 1415 | 1, 1416 | 0x18b2, 1417 | 0, 1418 | {0x32}, 1419 | 1, 1420 | 0x18b3, 1421 | 0, 1422 | {0x32}, 1423 | 1, 1424 | 0x18b4, 1425 | 0, 1426 | {0x32}, 1427 | 1, 1428 | 0x18b5, 1429 | 0, 1430 | {0x32}, 1431 | 3, 1432 | 0x43, 1433 | 0, 1434 | {0x02,0x14,0x00}, 1435 | 16, 1436 | 0x1400, 1437 | 0, 1438 | {0x02,0x18,0x15,0x00,0x02,0x18,0x3f,0x00,0x02,0x0f,0xed,0x00,0x02,0x18,0x2a,0x00}, 1439 | 16, 1440 | 0x1410, 1441 | 0, 1442 | {0x02,0x18,0x52,0x00,0x02,0x00,0x2a,0x00,0x02,0x00,0x32,0x00,0x02,0x00,0x42,0x00}, 1443 | 16, 1444 | 0x1420, 1445 | 0, 1446 | {0x02,0x17,0xc3,0x00,0x02,0x00,0x4a,0x00,0x02,0x13,0xff,0x00,0x02,0x17,0xaa,0x00}, 1447 | 16, 1448 | 0x1430, 1449 | 0, 1450 | {0x02,0x18,0xad,0x00,0x02,0x17,0x19,0x00,0x02,0x18,0xae,0x00,0x02,0x18,0xaf,0x00}, 1451 | 16, 1452 | 0x1440, 1453 | 0, 1454 | {0x02,0x18,0xb0,0x00,0x02,0x18,0xb1,0x00,0x02,0x18,0xb2,0x00,0x02,0x18,0xb3,0x00}, 1455 | 8, 1456 | 0x1450, 1457 | 0, 1458 | {0x02,0x18,0xb4,0x00,0x02,0x18,0xb5,0x00}, 1459 | 16, 1460 | 0x1777, 1461 | 0, 1462 | {0x90,0x7f,0xd6,0xe0,0x30,0xe7,0x12,0xe0,0x44,0x01,0xf0,0x7f,0x14,0x7e,0x00,0x12}, 1463 | 10, 1464 | 0x1787, 1465 | 0, 1466 | {0x17,0xdb,0x90,0x7f,0xd6,0xe0,0x54,0xfe,0xf0,0x22}, 1467 | 16, 1468 | 0x173a, 1469 | 0, 1470 | {0x90,0x7f,0xd6,0xe0,0x44,0x80,0xf0,0x43,0x87,0x01,0x00,0x00,0x00,0x00,0x00,0x22}, 1471 | 7, 1472 | 0x1458, 1473 | 0, 1474 | {0x90,0x7f,0xd6,0xe0,0x44,0x08,0xf0}, 1475 | 3, 1476 | 0x145f, 1477 | 0, 1478 | {0xe4,0xf5,0x0e}, 1479 | 4, 1480 | 0x1462, 1481 | 0, 1482 | {0xe0,0x54,0xfb,0xf0}, 1483 | 3, 1484 | 0x1466, 1485 | 0, 1486 | {0xe4,0xf5,0x0e}, 1487 | 16, 1488 | 0x1469, 1489 | 0, 1490 | {0xe0,0x44,0x08,0xf0,0x30,0x0b,0x04,0xe0,0x44,0x02,0xf0,0x7f,0xdc,0x7e,0x05,0x12}, 1491 | 16, 1492 | 0x1479, 1493 | 0, 1494 | {0x17,0xdb,0x90,0x7f,0x92,0xe0,0x30,0xe3,0x07,0x7f,0xdc,0x7e,0x05,0x12,0x17,0xdb}, 1495 | 16, 1496 | 0x1489, 1497 | 0, 1498 | {0x90,0x7f,0xab,0x74,0xff,0xf0,0x90,0x7f,0xa9,0xf0,0x90,0x7f,0xaa,0xf0,0x53,0x91}, 1499 | 8, 1500 | 0x1499, 1501 | 0, 1502 | {0xef,0x90,0x7f,0xd6,0xe0,0x54,0xf7,0xf0}, 1503 | 3, 1504 | 0x14a1, 1505 | 0, 1506 | {0xe4,0xf5,0x0e}, 1507 | 5, 1508 | 0x14a4, 1509 | 0, 1510 | {0xe0,0x44,0x04,0xf0,0x22}, 1511 | 16, 1512 | 0x174a, 1513 | 0, 1514 | {0x74,0x00,0xf5,0x86,0x90,0xfd,0xa5,0x7c,0x05,0xa3,0xe5,0x82,0x45,0x83,0x70,0xf9}, 1515 | 1, 1516 | 0x175a, 1517 | 0, 1518 | {0x22}, 1519 | 16, 1520 | 0x17db, 1521 | 0, 1522 | {0x8e,0x0f,0x8f,0x10,0xe5,0x10,0x15,0x10,0xae,0x0f,0x70,0x02,0x15,0x0f,0x4e,0x60}, 1523 | 7, 1524 | 0x17eb, 1525 | 0, 1526 | {0x05,0x12,0x17,0x4a,0x80,0xee,0x22}, 1527 | 8, 1528 | 0x1895, 1529 | 0, 1530 | {0xe4,0xf5,0x59,0xd2,0xe9,0xd2,0xaf,0x22}, 1531 | 16, 1532 | 0x1535, 1533 | 0, 1534 | {0x90,0x7f,0xa5,0xe0,0x20,0xe6,0xf9,0xc2,0xe9,0x90,0x7f,0xa5,0xe0,0x44,0x80,0xf0}, 1535 | 16, 1536 | 0x1545, 1537 | 0, 1538 | {0xef,0x25,0xe0,0x90,0x7f,0xa6,0xf0,0x90,0x7f,0xa5,0xe0,0x30,0xe0,0xf9,0x90,0x7f}, 1539 | 16, 1540 | 0x1555, 1541 | 0, 1542 | {0xa5,0xe0,0x44,0x40,0xf0,0x90,0x7f,0xa5,0xe0,0x20,0xe6,0xf9,0x90,0x7f,0xa5,0xe0}, 1543 | 6, 1544 | 0x1565, 1545 | 0, 1546 | {0x30,0xe1,0xd6,0xd2,0xe9,0x22}, 1547 | 16, 1548 | 0x1639, 1549 | 0, 1550 | {0xa9,0x07,0x90,0x7f,0xa5,0xe0,0x20,0xe6,0xf9,0xe5,0x59,0x70,0x23,0x90,0x7f,0xa5}, 1551 | 16, 1552 | 0x1649, 1553 | 0, 1554 | {0xe0,0x44,0x80,0xf0,0xe9,0x25,0xe0,0x90,0x7f,0xa6,0xf0,0x8d,0x54,0xaf,0x03,0xa9}, 1555 | 16, 1556 | 0x1659, 1557 | 0, 1558 | {0x07,0x75,0x55,0x01,0x8a,0x56,0x89,0x57,0xe4,0xf5,0x58,0x75,0x59,0x01,0xd3,0x22}, 1559 | 2, 1560 | 0x1669, 1561 | 0, 1562 | {0xc3,0x22}, 1563 | 16, 1564 | 0x15a0, 1565 | 0, 1566 | {0xa9,0x07,0x90,0x7f,0xa5,0xe0,0x20,0xe6,0xf9,0xe5,0x59,0x70,0x25,0x90,0x7f,0xa5}, 1567 | 16, 1568 | 0x15b0, 1569 | 0, 1570 | {0xe0,0x44,0x80,0xf0,0xe9,0x25,0xe0,0x44,0x01,0x90,0x7f,0xa6,0xf0,0x8d,0x54,0xaf}, 1571 | 16, 1572 | 0x15c0, 1573 | 0, 1574 | {0x03,0xa9,0x07,0x75,0x55,0x01,0x8a,0x56,0x89,0x57,0xe4,0xf5,0x58,0x75,0x59,0x03}, 1575 | 4, 1576 | 0x15d0, 1577 | 0, 1578 | {0xd3,0x22,0xc3,0x22}, 1579 | 3, 1580 | 0x4b, 1581 | 0, 1582 | {0x02,0x06,0xce}, 1583 | 16, 1584 | 0x6ce, 1585 | 0, 1586 | {0xc0,0xe0,0xc0,0x83,0xc0,0x82,0xc0,0x85,0xc0,0x84,0xc0,0x86,0x75,0x86,0x00,0xc0}, 1587 | 16, 1588 | 0x6de, 1589 | 0, 1590 | {0xd0,0x75,0xd0,0x00,0xc0,0x00,0xc0,0x01,0xc0,0x02,0xc0,0x03,0xc0,0x06,0xc0,0x07}, 1591 | 16, 1592 | 0x6ee, 1593 | 0, 1594 | {0x90,0x7f,0xa5,0xe0,0x30,0xe2,0x06,0x75,0x59,0x06,0x02,0x07,0xb9,0x90,0x7f,0xa5}, 1595 | 16, 1596 | 0x6fe, 1597 | 0, 1598 | {0xe0,0x20,0xe1,0x0c,0xe5,0x59,0x64,0x02,0x60,0x06,0x75,0x59,0x07,0x02,0x07,0xb9}, 1599 | 16, 1600 | 0x70e, 1601 | 0, 1602 | {0xaf,0x59,0xef,0x24,0xfe,0x60,0x5f,0x14,0x60,0x36,0x24,0xfe,0x70,0x03,0x02,0x07}, 1603 | 16, 1604 | 0x71e, 1605 | 0, 1606 | {0xaa,0x24,0xfc,0x70,0x03,0x02,0x07,0xb6,0x24,0x08,0x60,0x03,0x02,0x07,0xb9,0xab}, 1607 | 16, 1608 | 0x72e, 1609 | 0, 1610 | {0x55,0xaa,0x56,0xa9,0x57,0xaf,0x58,0x05,0x58,0x8f,0x82,0x75,0x83,0x00,0x12,0x06}, 1611 | 16, 1612 | 0x73e, 1613 | 0, 1614 | {0x50,0x90,0x7f,0xa6,0xf0,0xe5,0x58,0x65,0x54,0x70,0x70,0x75,0x59,0x05,0x80,0x6b}, 1615 | 16, 1616 | 0x74e, 1617 | 0, 1618 | {0x90,0x7f,0xa6,0xe0,0xab,0x55,0xaa,0x56,0xa9,0x57,0xae,0x58,0x8e,0x82,0x75,0x83}, 1619 | 16, 1620 | 0x75e, 1621 | 0, 1622 | {0x00,0x12,0x06,0x7d,0x75,0x59,0x02,0xe5,0x54,0x64,0x01,0x70,0x4e,0x90,0x7f,0xa5}, 1623 | 16, 1624 | 0x76e, 1625 | 0, 1626 | {0xe0,0x44,0x20,0xf0,0x80,0x45,0xe5,0x54,0x24,0xfe,0xb5,0x58,0x07,0x90,0x7f,0xa5}, 1627 | 16, 1628 | 0x77e, 1629 | 0, 1630 | {0xe0,0x44,0x20,0xf0,0xe5,0x54,0x14,0xb5,0x58,0x0a,0x90,0x7f,0xa5,0xe0,0x44,0x40}, 1631 | 16, 1632 | 0x78e, 1633 | 0, 1634 | {0xf0,0x75,0x59,0x00,0x90,0x7f,0xa6,0xe0,0xab,0x55,0xaa,0x56,0xa9,0x57,0xae,0x58}, 1635 | 16, 1636 | 0x79e, 1637 | 0, 1638 | {0x8e,0x82,0x75,0x83,0x00,0x12,0x06,0x7d,0x05,0x58,0x80,0x0f,0x90,0x7f,0xa5,0xe0}, 1639 | 16, 1640 | 0x7ae, 1641 | 0, 1642 | {0x44,0x40,0xf0,0x75,0x59,0x00,0x80,0x03,0x75,0x59,0x00,0x53,0x91,0xdf,0xd0,0x07}, 1643 | 16, 1644 | 0x7be, 1645 | 0, 1646 | {0xd0,0x06,0xd0,0x03,0xd0,0x02,0xd0,0x01,0xd0,0x00,0xd0,0xd0,0xd0,0x86,0xd0,0x84}, 1647 | 9, 1648 | 0x7ce, 1649 | 0, 1650 | {0xd0,0x85,0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32}, 1651 | 2, 1652 | 0x16cc, 1653 | 0, 1654 | {0xa9,0x07}, 1655 | 16, 1656 | 0x16ce, 1657 | 0, 1658 | {0xae,0x52,0xaf,0x53,0x8f,0x82,0x8e,0x83,0xa3,0xe0,0x64,0x03,0x70,0x17,0xad,0x01}, 1659 | 16, 1660 | 0x16de, 1661 | 0, 1662 | {0x19,0xed,0x70,0x01,0x22,0x8f,0x82,0x8e,0x83,0xe0,0x7c,0x00,0x2f,0xfd,0xec,0x3e}, 1663 | 9, 1664 | 0x16ee, 1665 | 0, 1666 | {0xfe,0xaf,0x05,0x80,0xdf,0x7e,0x00,0x7f,0x00}, 1667 | 1, 1668 | 0x16f7, 1669 | 0, 1670 | {0x22}, 1671 | 2, 1672 | 0x14f4, 1673 | 0, 1674 | {0xad,0x07}, 1675 | 16, 1676 | 0x14f6, 1677 | 0, 1678 | {0xe4,0xfc,0xae,0x4f,0xaf,0x50,0x8f,0x82,0x8e,0x83,0xa3,0xe0,0x64,0x02,0x70,0x2a}, 1679 | 16, 1680 | 0x1506, 1681 | 0, 1682 | {0xab,0x04,0x0c,0xeb,0xb5,0x05,0x01,0x22,0x8f,0x82,0x8e,0x83,0xa3,0xa3,0xe0,0xfa}, 1683 | 16, 1684 | 0x1516, 1685 | 0, 1686 | {0xa3,0xe0,0x8a,0x17,0xf5,0x18,0x62,0x17,0xe5,0x17,0x62,0x18,0xe5,0x18,0x62,0x17}, 1687 | 14, 1688 | 0x1526, 1689 | 0, 1690 | {0x2f,0xfb,0xe5,0x17,0x3e,0xfe,0xaf,0x03,0x80,0xcc,0x7e,0x00,0x7f,0x00}, 1691 | 1, 1692 | 0x1534, 1693 | 0, 1694 | {0x22}, 1695 | 16, 1696 | 0x13e3, 1697 | 0, 1698 | {0x12,0x15,0xa0,0xe5,0x59,0x24,0xfa,0x60,0x0e,0x14,0x60,0x06,0x24,0x07,0x70,0xf3}, 1699 | 12, 1700 | 0x13f3, 1701 | 0, 1702 | {0xd3,0x22,0xe4,0xf5,0x59,0xd3,0x22,0xe4,0xf5,0x59,0xd3,0x22}, 1703 | 16, 1704 | 0x175b, 1705 | 0, 1706 | {0x12,0x16,0x39,0xe5,0x59,0x24,0xfa,0x60,0x0e,0x14,0x60,0x06,0x24,0x07,0x70,0xf3}, 1707 | 12, 1708 | 0x176b, 1709 | 0, 1710 | {0xd3,0x22,0xe4,0xf5,0x59,0xd3,0x22,0xe4,0xf5,0x59,0xd3,0x22}, 1711 | 16, 1712 | 0xabd, 1713 | 0, 1714 | {0x12,0x01,0x00,0x01,0x00,0x00,0x00,0x40,0x5e,0x09,0x01,0x01,0x01,0x00,0x01,0x02}, 1715 | 16, 1716 | 0xacd, 1717 | 0, 1718 | {0x00,0x01,0x09,0x02,0x62,0x00,0x03,0x01,0x00,0x80,0x32,0x09,0x04,0x00,0x00,0x02}, 1719 | 16, 1720 | 0xadd, 1721 | 0, 1722 | {0x03,0x00,0x00,0x00,0x09,0x21,0x10,0x01,0x00,0x01,0x22,0x1c,0x00,0x07,0x05,0x81}, 1723 | 16, 1724 | 0xaed, 1725 | 0, 1726 | {0x03,0x40,0x00,0x04,0x07,0x05,0x02,0x03,0x40,0x00,0x04,0x09,0x04,0x01,0x00,0x02}, 1727 | 16, 1728 | 0xafd, 1729 | 0, 1730 | {0x03,0x01,0x01,0x00,0x09,0x21,0x10,0x01,0x00,0x01,0x22,0x37,0x00,0x07,0x05,0x83}, 1731 | 16, 1732 | 0xb0d, 1733 | 0, 1734 | {0x03,0x08,0x00,0x04,0x07,0x05,0x03,0x03,0x08,0x00,0x0a,0x09,0x04,0x02,0x00,0x01}, 1735 | 16, 1736 | 0xb1d, 1737 | 0, 1738 | {0x03,0x01,0x02,0x00,0x09,0x21,0x10,0x01,0x00,0x01,0x22,0x2c,0x00,0x07,0x05,0x84}, 1739 | 16, 1740 | 0xb2d, 1741 | 0, 1742 | {0x03,0x40,0x00,0x04,0x06,0xa0,0xff,0x09,0x01,0xa1,0x01,0x09,0x03,0x09,0x04,0x15}, 1743 | 16, 1744 | 0xb3d, 1745 | 0, 1746 | {0x80,0x25,0x7f,0x75,0x08,0x95,0x08,0x81,0x02,0x09,0x05,0x09,0x06,0x91,0x02,0xc0}, 1747 | 16, 1748 | 0xb4d, 1749 | 0, 1750 | {0x05,0x01,0x09,0x06,0xa1,0x01,0x05,0x07,0x19,0xe0,0x29,0xe7,0x15,0x00,0x25,0x01}, 1751 | 16, 1752 | 0xb5d, 1753 | 0, 1754 | {0x75,0x01,0x95,0x08,0x81,0x02,0x75,0x01,0x95,0x08,0x81,0x01,0x19,0x00,0x29,0x65}, 1755 | 16, 1756 | 0xb6d, 1757 | 0, 1758 | {0x75,0x08,0x95,0x06,0x81,0x00,0x05,0x08,0x19,0x01,0x29,0x05,0x75,0x01,0x95,0x05}, 1759 | 16, 1760 | 0xb7d, 1761 | 0, 1762 | {0x91,0x02,0x95,0x03,0x91,0x01,0xc0,0x05,0x01,0x09,0x02,0xa1,0x01,0x09,0x01,0xa1}, 1763 | 16, 1764 | 0xb8d, 1765 | 0, 1766 | {0x00,0x05,0x09,0x19,0x01,0x29,0x08,0x15,0x00,0x25,0x01,0x95,0x08,0x75,0x01,0x81}, 1767 | 16, 1768 | 0xb9d, 1769 | 0, 1770 | {0x02,0x05,0x01,0x09,0x30,0x09,0x31,0x15,0x81,0x25,0x7f,0x75,0x08,0x95,0x02,0x81}, 1771 | 16, 1772 | 0xbad, 1773 | 0, 1774 | {0x06,0xc0,0xc0,0x0b,0x31,0x0b,0x4d,0x0b,0x84,0x1c,0x37,0x2c,0x0a,0xe1,0x0b,0x01}, 1775 | 16, 1776 | 0xbbd, 1777 | 0, 1778 | {0x0b,0x21,0x04,0x03,0x09,0x04,0x26,0x03,0x49,0x00,0x6e,0x00,0x74,0x00,0x65,0x00}, 1779 | 16, 1780 | 0xbcd, 1781 | 0, 1782 | {0x6c,0x00,0x6c,0x00,0x69,0x00,0x54,0x00,0x6f,0x00,0x6f,0x00,0x6c,0x00,0x73,0x00}, 1783 | 16, 1784 | 0xbdd, 1785 | 0, 1786 | {0x2c,0x00,0x20,0x00,0x49,0x00,0x6e,0x00,0x63,0x00,0x2e,0x00,0x20,0x03,0x49,0x00}, 1787 | 16, 1788 | 0xbed, 1789 | 0, 1790 | {0x6e,0x00,0x74,0x00,0x65,0x00,0x6c,0x00,0x6c,0x00,0x69,0x00,0x4b,0x00,0x65,0x00}, 1791 | 14, 1792 | 0xbfd, 1793 | 0, 1794 | {0x79,0x00,0x73,0x00,0x20,0x00,0x55,0x00,0x53,0x00,0x42,0x00,0x00,0x00}, 1795 | 3, 1796 | 0x0, 1797 | 0, 1798 | {0x02,0x11,0x3d}, 1799 | 12, 1800 | 0x113d, 1801 | 0, 1802 | {0x78,0x7f,0xe4,0xf6,0xd8,0xfd,0x75,0x81,0x59,0x02,0x11,0x84}, 1803 | 16, 1804 | 0x541, 1805 | 0, 1806 | {0xe7,0x09,0xf6,0x08,0xdf,0xfa,0x80,0x46,0xe7,0x09,0xf2,0x08,0xdf,0xfa,0x80,0x3e}, 1807 | 16, 1808 | 0x551, 1809 | 0, 1810 | {0x88,0x82,0x8c,0x83,0xe7,0x09,0xf0,0xa3,0xdf,0xfa,0x80,0x32,0xe3,0x09,0xf6,0x08}, 1811 | 16, 1812 | 0x561, 1813 | 0, 1814 | {0xdf,0xfa,0x80,0x78,0xe3,0x09,0xf2,0x08,0xdf,0xfa,0x80,0x70,0x88,0x82,0x8c,0x83}, 1815 | 16, 1816 | 0x571, 1817 | 0, 1818 | {0xe3,0x09,0xf0,0xa3,0xdf,0xfa,0x80,0x64,0x89,0x82,0x8a,0x83,0xe0,0xa3,0xf6,0x08}, 1819 | 16, 1820 | 0x581, 1821 | 0, 1822 | {0xdf,0xfa,0x80,0x58,0x89,0x82,0x8a,0x83,0xe0,0xa3,0xf2,0x08,0xdf,0xfa,0x80,0x4c}, 1823 | 16, 1824 | 0x591, 1825 | 0, 1826 | {0x80,0xd2,0x80,0xfa,0x80,0xc6,0x80,0xd4,0x80,0x69,0x80,0xf2,0x80,0x33,0x80,0x10}, 1827 | 16, 1828 | 0x5a1, 1829 | 0, 1830 | {0x80,0xa6,0x80,0xea,0x80,0x9a,0x80,0xa8,0x80,0xda,0x80,0xe2,0x80,0xca,0x80,0x33}, 1831 | 16, 1832 | 0x5b1, 1833 | 0, 1834 | {0x89,0x82,0x8a,0x83,0xec,0xfa,0xe4,0x93,0xa3,0xc8,0xc5,0x82,0xc8,0xcc,0xc5,0x83}, 1835 | 16, 1836 | 0x5c1, 1837 | 0, 1838 | {0xcc,0xf0,0xa3,0xc8,0xc5,0x82,0xc8,0xcc,0xc5,0x83,0xcc,0xdf,0xe9,0xde,0xe7,0x80}, 1839 | 16, 1840 | 0x5d1, 1841 | 0, 1842 | {0x0d,0x89,0x82,0x8a,0x83,0xe4,0x93,0xa3,0xf6,0x08,0xdf,0xf9,0xec,0xfa,0xa9,0xf0}, 1843 | 16, 1844 | 0x5e1, 1845 | 0, 1846 | {0xed,0xfb,0x22,0x89,0x82,0x8a,0x83,0xec,0xfa,0xe0,0xa3,0xc8,0xc5,0x82,0xc8,0xcc}, 1847 | 16, 1848 | 0x5f1, 1849 | 0, 1850 | {0xc5,0x83,0xcc,0xf0,0xa3,0xc8,0xc5,0x82,0xc8,0xcc,0xc5,0x83,0xcc,0xdf,0xea,0xde}, 1851 | 16, 1852 | 0x601, 1853 | 0, 1854 | {0xe8,0x80,0xdb,0x89,0x82,0x8a,0x83,0xe4,0x93,0xa3,0xf2,0x08,0xdf,0xf9,0x80,0xcc}, 1855 | 16, 1856 | 0x611, 1857 | 0, 1858 | {0x88,0xf0,0xef,0x60,0x01,0x0e,0x4e,0x60,0xc3,0x88,0xf0,0xed,0x24,0x02,0xb4,0x04}, 1859 | 16, 1860 | 0x621, 1861 | 0, 1862 | {0x00,0x50,0xb9,0xf5,0x82,0xeb,0x24,0x02,0xb4,0x04,0x00,0x50,0xaf,0x23,0x23,0x45}, 1863 | 6, 1864 | 0x631, 1865 | 0, 1866 | {0x82,0x23,0x90,0x05,0x91,0x73}, 1867 | 16, 1868 | 0x637, 1869 | 0, 1870 | {0xbb,0x01,0x06,0x89,0x82,0x8a,0x83,0xe0,0x22,0x50,0x02,0xe7,0x22,0xbb,0xfe,0x02}, 1871 | 9, 1872 | 0x647, 1873 | 0, 1874 | {0xe3,0x22,0x89,0x82,0x8a,0x83,0xe4,0x93,0x22}, 1875 | 16, 1876 | 0x650, 1877 | 0, 1878 | {0xbb,0x01,0x0c,0xe5,0x82,0x29,0xf5,0x82,0xe5,0x83,0x3a,0xf5,0x83,0xe0,0x22,0x50}, 1879 | 16, 1880 | 0x660, 1881 | 0, 1882 | {0x06,0xe9,0x25,0x82,0xf8,0xe6,0x22,0xbb,0xfe,0x06,0xe9,0x25,0x82,0xf8,0xe2,0x22}, 1883 | 13, 1884 | 0x670, 1885 | 0, 1886 | {0xe5,0x82,0x29,0xf5,0x82,0xe5,0x83,0x3a,0xf5,0x83,0xe4,0x93,0x22}, 1887 | 16, 1888 | 0x67d, 1889 | 0, 1890 | {0xf8,0xbb,0x01,0x0d,0xe5,0x82,0x29,0xf5,0x82,0xe5,0x83,0x3a,0xf5,0x83,0xe8,0xf0}, 1891 | 16, 1892 | 0x68d, 1893 | 0, 1894 | {0x22,0x50,0x06,0xe9,0x25,0x82,0xc8,0xf6,0x22,0xbb,0xfe,0x05,0xe9,0x25,0x82,0xc8}, 1895 | 2, 1896 | 0x69d, 1897 | 0, 1898 | {0xf2,0x22}, 1899 | 16, 1900 | 0x69f, 1901 | 0, 1902 | {0xef,0x8d,0xf0,0xa4,0xa8,0xf0,0xcf,0x8c,0xf0,0xa4,0x28,0xce,0x8d,0xf0,0xa4,0x2e}, 1903 | 2, 1904 | 0x6af, 1905 | 0, 1906 | {0xfe,0x22}, 1907 | 16, 1908 | 0x6b1, 1909 | 0, 1910 | {0xeb,0x9f,0xf5,0xf0,0xea,0x9e,0x42,0xf0,0xe9,0x9d,0x42,0xf0,0xe8,0x9c,0x45,0xf0}, 1911 | 1, 1912 | 0x6c1, 1913 | 0, 1914 | {0x22}, 1915 | 12, 1916 | 0x6c2, 1917 | 0, 1918 | {0xa4,0x25,0x82,0xf5,0x82,0xe5,0xf0,0x35,0x83,0xf5,0x83,0x22}, 1919 | 16, 1920 | 0x1149, 1921 | 0, 1922 | {0x02,0x0e,0xe7,0xe4,0x93,0xa3,0xf8,0xe4,0x93,0xa3,0x40,0x03,0xf6,0x80,0x01,0xf2}, 1923 | 16, 1924 | 0x1159, 1925 | 0, 1926 | {0x08,0xdf,0xf4,0x80,0x29,0xe4,0x93,0xa3,0xf8,0x54,0x07,0x24,0x0c,0xc8,0xc3,0x33}, 1927 | 16, 1928 | 0x1169, 1929 | 0, 1930 | {0xc4,0x54,0x0f,0x44,0x20,0xc8,0x83,0x40,0x04,0xf4,0x56,0x80,0x01,0x46,0xf6,0xdf}, 1931 | 16, 1932 | 0x1179, 1933 | 0, 1934 | {0xe4,0x80,0x0b,0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x90,0x18,0x65,0xe4,0x7e}, 1935 | 16, 1936 | 0x1189, 1937 | 0, 1938 | {0x01,0x93,0x60,0xbc,0xa3,0xff,0x54,0x3f,0x30,0xe5,0x09,0x54,0x1f,0xfe,0xe4,0x93}, 1939 | 16, 1940 | 0x1199, 1941 | 0, 1942 | {0xa3,0x60,0x01,0x0e,0xcf,0x54,0xc0,0x25,0xe0,0x60,0xa8,0x40,0xb8,0xe4,0x93,0xa3}, 1943 | 16, 1944 | 0x11a9, 1945 | 0, 1946 | {0xfa,0xe4,0x93,0xa3,0xf8,0xe4,0x93,0xa3,0xc8,0xc5,0x82,0xc8,0xca,0xc5,0x83,0xca}, 1947 | 16, 1948 | 0x11b9, 1949 | 0, 1950 | {0xf0,0xa3,0xc8,0xc5,0x82,0xc8,0xca,0xc5,0x83,0xca,0xdf,0xe9,0xde,0xe7,0x80,0xbe}, 1951 | 1, 1952 | 0x1876, 1953 | 0, 1954 | {0x00}, 1955 | 0, 1956 | 0x0, 1957 | 1, 1958 | {0} 1959 | }; 1960 | -------------------------------------------------------------------------------- /src/ik_loader.h: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2023 Ha Thach (tinyusb.org) for Adafruit Industries 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | // From https://github.com/ATMakersOrg/OpenIKeys/blob/master/original/IntelliKeys/WindowsOld/Win/Loading%20Driver/loader.c 26 | static const INTEL_HEX_RECORD ik_loader[] = { 27 | 16, 28 | 0x146c, 29 | 0, 30 | {0xc2,0x00,0x90,0x7f,0xa5,0xe0,0x54,0x18,0xff,0x13,0x13,0x13,0x54,0x1f,0x44,0x50}, 31 | 16, 32 | 0x147c, 33 | 0, 34 | {0xf5,0x1c,0x13,0x92,0x01,0xd2,0xe8,0x90,0x7f,0xab,0x74,0xff,0xf0,0x90,0x7f,0xa9}, 35 | 16, 36 | 0x148c, 37 | 0, 38 | {0xf0,0x90,0x7f,0xaa,0xf0,0x53,0x91,0xef,0x90,0x7f,0x95,0xe0,0x44,0xc0,0xf0,0x90}, 39 | 16, 40 | 0x149c, 41 | 0, 42 | {0x7f,0xaf,0xe0,0x44,0x01,0xf0,0x90,0x7f,0xae,0xe0,0x44,0x05,0xf0,0xd2,0xaf,0x12}, 43 | 13, 44 | 0x14ac, 45 | 0, 46 | {0x17,0x5f,0x30,0x00,0xfd,0x12,0x11,0x00,0xc2,0x00,0x80,0xf6,0x22}, 47 | 16, 48 | 0x1100, 49 | 0, 50 | {0x90,0x7f,0xe9,0xe0,0x24,0x5d,0x60,0x0d,0x14,0x70,0x03,0x02,0x12,0x44,0x24,0x02}, 51 | 16, 52 | 0x1110, 53 | 0, 54 | {0x60,0x03,0x02,0x12,0x4a,0x90,0x7f,0xea,0xe0,0x75,0x08,0x00,0xf5,0x09,0xa3,0xe0}, 55 | 16, 56 | 0x1120, 57 | 0, 58 | {0xfe,0xe4,0x25,0x09,0xf5,0x09,0xee,0x35,0x08,0xf5,0x08,0x90,0x7f,0xee,0xe0,0x75}, 59 | 16, 60 | 0x1130, 61 | 0, 62 | {0x0a,0x00,0xf5,0x0b,0xa3,0xe0,0xfe,0xe4,0x25,0x0b,0xf5,0x0b,0xee,0x35,0x0a,0xf5}, 63 | 16, 64 | 0x1140, 65 | 0, 66 | {0x0a,0x90,0x7f,0xe8,0xe0,0x64,0xc0,0x60,0x03,0x02,0x11,0xd4,0xe5,0x0b,0x45,0x0a}, 67 | 16, 68 | 0x1150, 69 | 0, 70 | {0x70,0x03,0x02,0x12,0x4a,0xc3,0xe5,0x0b,0x94,0x40,0xe5,0x0a,0x94,0x00,0x50,0x08}, 71 | 16, 72 | 0x1160, 73 | 0, 74 | {0x85,0x0a,0x0c,0x85,0x0b,0x0d,0x80,0x06,0x75,0x0c,0x00,0x75,0x0d,0x40,0x90,0x7f}, 75 | 16, 76 | 0x1170, 77 | 0, 78 | {0xe9,0xe0,0xb4,0xa3,0x25,0xae,0x0c,0xaf,0x0d,0xaa,0x08,0xa9,0x09,0x7b,0x01,0xc0}, 79 | 16, 80 | 0x1180, 81 | 0, 82 | {0x03,0xc0,0x02,0xc0,0x01,0x7a,0x7f,0x79,0x00,0x78,0x00,0x7c,0x7f,0xad,0x03,0xd0}, 83 | 16, 84 | 0x1190, 85 | 0, 86 | {0x01,0xd0,0x02,0xd0,0x03,0x12,0x13,0x56,0x80,0x0f,0xaf,0x09,0xae,0x08,0xad,0x0d}, 87 | 16, 88 | 0x11a0, 89 | 0, 90 | {0x7a,0x7f,0x79,0x00,0x7b,0x00,0x12,0x15,0xa4,0x90,0x7f,0xb5,0xe5,0x0d,0xf0,0xe5}, 91 | 16, 92 | 0x11b0, 93 | 0, 94 | {0x0d,0x25,0x09,0xf5,0x09,0xe5,0x0c,0x35,0x08,0xf5,0x08,0xc3,0xe5,0x0b,0x95,0x0d}, 95 | 16, 96 | 0x11c0, 97 | 0, 98 | {0xf5,0x0b,0xe5,0x0a,0x95,0x0c,0xf5,0x0a,0x90,0x7f,0xb4,0xe0,0x20,0xe2,0x03,0x02}, 99 | 16, 100 | 0x11d0, 101 | 0, 102 | {0x11,0x4c,0x80,0xf4,0x90,0x7f,0xe8,0xe0,0x64,0x40,0x70,0x6e,0xe5,0x0b,0x45,0x0a}, 103 | 16, 104 | 0x11e0, 105 | 0, 106 | {0x60,0x68,0xe4,0x90,0x7f,0xc5,0xf0,0x90,0x7f,0xb4,0xe0,0x20,0xe3,0xf9,0x90,0x7f}, 107 | 16, 108 | 0x11f0, 109 | 0, 110 | {0xc5,0xe0,0x75,0x0c,0x00,0xf5,0x0d,0x90,0x7f,0xe9,0xe0,0xb4,0xa3,0x15,0xae,0x0c}, 111 | 16, 112 | 0x1200, 113 | 0, 114 | {0xaf,0x0d,0xa8,0x09,0xac,0x08,0x7d,0x01,0x7b,0x01,0x7a,0x7e,0x79,0xc0,0x12,0x13}, 115 | 16, 116 | 0x1210, 117 | 0, 118 | {0x56,0x80,0x0f,0xaf,0x09,0xae,0x08,0xad,0x0d,0x7a,0x7f,0x79,0x00,0x7b,0x00,0x12}, 119 | 16, 120 | 0x1220, 121 | 0, 122 | {0x14,0xb9,0xe5,0x0d,0x25,0x09,0xf5,0x09,0xe5,0x0c,0x35,0x08,0xf5,0x08,0xc3,0xe5}, 123 | 16, 124 | 0x1230, 125 | 0, 126 | {0x0b,0x95,0x0d,0xf5,0x0b,0xe5,0x0a,0x95,0x0c,0xf5,0x0a,0x90,0x7f,0xb4,0xe0,0x44}, 127 | 10, 128 | 0x1240, 129 | 0, 130 | {0x02,0xf0,0x80,0x98,0x90,0x7f,0xea,0xe0,0xf5,0x1c}, 131 | 1, 132 | 0x124a, 133 | 0, 134 | {0x22}, 135 | 6, 136 | 0x1558, 137 | 0, 138 | {0xab,0x07,0xaa,0x06,0xac,0x05}, 139 | 16, 140 | 0x155e, 141 | 0, 142 | {0xe4,0xfd,0x30,0x01,0x11,0xea,0xff,0xae,0x05,0x0d,0xee,0x24,0x00,0xf5,0x82,0xe4}, 143 | 16, 144 | 0x156e, 145 | 0, 146 | {0x34,0xe0,0xf5,0x83,0xef,0xf0,0xeb,0xae,0x05,0x0d,0x74,0x00,0x2e,0xf5,0x82,0xe4}, 147 | 16, 148 | 0x157e, 149 | 0, 150 | {0x34,0xe0,0xf5,0x83,0xeb,0xf0,0xaf,0x05,0x0d,0x74,0x00,0x2f,0xf5,0x82,0xe4,0x34}, 151 | 16, 152 | 0x158e, 153 | 0, 154 | {0xe0,0xf5,0x83,0xec,0xf0,0xaf,0x1c,0x7a,0xe0,0x7b,0x00,0x12,0x17,0x20,0x7f,0x0a}, 155 | 5, 156 | 0x159e, 157 | 0, 158 | {0x7e,0x00,0x12,0x17,0x3c}, 159 | 1, 160 | 0x15a3, 161 | 0, 162 | {0x22}, 163 | 10, 164 | 0x14b9, 165 | 0, 166 | {0x8e,0x0e,0x8f,0x0f,0x8d,0x10,0x8a,0x11,0x8b,0x12}, 167 | 16, 168 | 0x14c3, 169 | 0, 170 | {0xe4,0xf5,0x13,0xe5,0x13,0xc3,0x95,0x10,0x50,0x20,0x05,0x0f,0xe5,0x0f,0xae,0x0e}, 171 | 16, 172 | 0x14d3, 173 | 0, 174 | {0x70,0x02,0x05,0x0e,0x14,0xff,0xe5,0x12,0x25,0x13,0xf5,0x82,0xe4,0x35,0x11,0xf5}, 175 | 10, 176 | 0x14e3, 177 | 0, 178 | {0x83,0xe0,0xfd,0x12,0x15,0x58,0x05,0x13,0x80,0xd9}, 179 | 1, 180 | 0x14ed, 181 | 0, 182 | {0x22}, 183 | 10, 184 | 0x15a4, 185 | 0, 186 | {0x8e,0x0e,0x8f,0x0f,0x8d,0x10,0x8a,0x11,0x8b,0x12}, 187 | 16, 188 | 0x15ae, 189 | 0, 190 | {0xe4,0xfd,0x30,0x01,0x12,0xe5,0x0e,0xff,0xae,0x05,0x0d,0xee,0x24,0x03,0xf5,0x82}, 191 | 16, 192 | 0x15be, 193 | 0, 194 | {0xe4,0x34,0xe0,0xf5,0x83,0xef,0xf0,0xe5,0x0f,0xae,0x05,0x0d,0x74,0x03,0x2e,0xf5}, 195 | 16, 196 | 0x15ce, 197 | 0, 198 | {0x82,0xe4,0x34,0xe0,0xf5,0x83,0xe5,0x0f,0xf0,0xaf,0x1c,0x7a,0xe0,0x7b,0x03,0x12}, 199 | 13, 200 | 0x15de, 201 | 0, 202 | {0x17,0x20,0xaf,0x1c,0xad,0x10,0xab,0x12,0xaa,0x11,0x12,0x17,0x04}, 203 | 1, 204 | 0x15eb, 205 | 0, 206 | {0x22}, 207 | 16, 208 | 0x166e, 209 | 0, 210 | {0xc0,0xe0,0xc0,0x83,0xc0,0x82,0xc0,0x85,0xc0,0x84,0xc0,0x86,0x75,0x86,0x00,0xd2}, 211 | 16, 212 | 0x167e, 213 | 0, 214 | {0x00,0x53,0x91,0xef,0x90,0x7f,0xab,0x74,0x01,0xf0,0xd0,0x86,0xd0,0x84,0xd0,0x85}, 215 | 7, 216 | 0x168e, 217 | 0, 218 | {0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32}, 219 | 16, 220 | 0x1644, 221 | 0, 222 | {0xc0,0xe0,0xc0,0x83,0xc0,0x82,0xc0,0x85,0xc0,0x84,0xc0,0x86,0x75,0x86,0x00,0x90}, 223 | 16, 224 | 0x1654, 225 | 0, 226 | {0x7f,0xc4,0xe4,0xf0,0x53,0x91,0xef,0x90,0x7f,0xab,0x74,0x04,0xf0,0xd0,0x86,0xd0}, 227 | 10, 228 | 0x1664, 229 | 0, 230 | {0x84,0xd0,0x85,0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32}, 231 | 16, 232 | 0x1695, 233 | 0, 234 | {0xc0,0xe0,0xc0,0x83,0xc0,0x82,0xc0,0x85,0xc0,0x84,0xc0,0x86,0x75,0x86,0x00,0x53}, 235 | 16, 236 | 0x16a5, 237 | 0, 238 | {0x91,0xef,0x90,0x7f,0xab,0x74,0x02,0xf0,0xd0,0x86,0xd0,0x84,0xd0,0x85,0xd0,0x82}, 239 | 5, 240 | 0x16b5, 241 | 0, 242 | {0xd0,0x83,0xd0,0xe0,0x32}, 243 | 16, 244 | 0x16ba, 245 | 0, 246 | {0xc0,0xe0,0xc0,0x83,0xc0,0x82,0xc0,0x85,0xc0,0x84,0xc0,0x86,0x75,0x86,0x00,0x53}, 247 | 16, 248 | 0x16ca, 249 | 0, 250 | {0x91,0xef,0x90,0x7f,0xab,0x74,0x10,0xf0,0xd0,0x86,0xd0,0x84,0xd0,0x85,0xd0,0x82}, 251 | 5, 252 | 0x16da, 253 | 0, 254 | {0xd0,0x83,0xd0,0xe0,0x32}, 255 | 1, 256 | 0x14ff, 257 | 0, 258 | {0x32}, 259 | 16, 260 | 0x16df, 261 | 0, 262 | {0xc0,0xe0,0xc0,0x83,0xc0,0x82,0xc0,0x85,0xc0,0x84,0xc0,0x86,0x75,0x86,0x00,0x53}, 263 | 16, 264 | 0x16ef, 265 | 0, 266 | {0x91,0xef,0x90,0x7f,0xab,0x74,0x08,0xf0,0xd0,0x86,0xd0,0x84,0xd0,0x85,0xd0,0x82}, 267 | 5, 268 | 0x16ff, 269 | 0, 270 | {0xd0,0x83,0xd0,0xe0,0x32}, 271 | 1, 272 | 0x1767, 273 | 0, 274 | {0x32}, 275 | 1, 276 | 0x1768, 277 | 0, 278 | {0x32}, 279 | 1, 280 | 0x1769, 281 | 0, 282 | {0x32}, 283 | 1, 284 | 0x176a, 285 | 0, 286 | {0x32}, 287 | 1, 288 | 0x176b, 289 | 0, 290 | {0x32}, 291 | 1, 292 | 0x176c, 293 | 0, 294 | {0x32}, 295 | 1, 296 | 0x176d, 297 | 0, 298 | {0x32}, 299 | 1, 300 | 0x176e, 301 | 0, 302 | {0x32}, 303 | 1, 304 | 0x176f, 305 | 0, 306 | {0x32}, 307 | 1, 308 | 0x1770, 309 | 0, 310 | {0x32}, 311 | 1, 312 | 0x1771, 313 | 0, 314 | {0x32}, 315 | 1, 316 | 0x1772, 317 | 0, 318 | {0x32}, 319 | 1, 320 | 0x1773, 321 | 0, 322 | {0x32}, 323 | 1, 324 | 0x1774, 325 | 0, 326 | {0x32}, 327 | 1, 328 | 0x1775, 329 | 0, 330 | {0x32}, 331 | 1, 332 | 0x1776, 333 | 0, 334 | {0x32}, 335 | 3, 336 | 0x43, 337 | 0, 338 | {0x02,0x15,0x00}, 339 | 16, 340 | 0x1500, 341 | 0, 342 | {0x02,0x16,0x6e,0x00,0x02,0x16,0x95,0x00,0x02,0x16,0x44,0x00,0x02,0x16,0xdf,0x00}, 343 | 16, 344 | 0x1510, 345 | 0, 346 | {0x02,0x16,0xba,0x00,0x02,0x14,0xff,0x00,0x02,0x17,0x67,0x00,0x02,0x17,0x68,0x00}, 347 | 16, 348 | 0x1520, 349 | 0, 350 | {0x02,0x17,0x69,0x00,0x02,0x17,0x6a,0x00,0x02,0x17,0x6b,0x00,0x02,0x17,0x6c,0x00}, 351 | 16, 352 | 0x1530, 353 | 0, 354 | {0x02,0x17,0x6d,0x00,0x02,0x17,0x6e,0x00,0x02,0x17,0x6f,0x00,0x02,0x17,0x70,0x00}, 355 | 16, 356 | 0x1540, 357 | 0, 358 | {0x02,0x17,0x71,0x00,0x02,0x17,0x72,0x00,0x02,0x17,0x73,0x00,0x02,0x17,0x74,0x00}, 359 | 8, 360 | 0x1550, 361 | 0, 362 | {0x02,0x17,0x75,0x00,0x02,0x17,0x76,0x00}, 363 | 16, 364 | 0x173c, 365 | 0, 366 | {0x8e,0x14,0x8f,0x15,0xe5,0x15,0x15,0x15,0xae,0x14,0x70,0x02,0x15,0x14,0x4e,0x60}, 367 | 7, 368 | 0x174c, 369 | 0, 370 | {0x05,0x12,0x14,0xee,0x80,0xee,0x22}, 371 | 8, 372 | 0x175f, 373 | 0, 374 | {0xe4,0xf5,0x1b,0xd2,0xe9,0xd2,0xaf,0x22}, 375 | 16, 376 | 0x1619, 377 | 0, 378 | {0xa9,0x07,0xe5,0x1b,0x70,0x23,0x90,0x7f,0xa5,0xe0,0x44,0x80,0xf0,0xe9,0x25,0xe0}, 379 | 16, 380 | 0x1629, 381 | 0, 382 | {0x90,0x7f,0xa6,0xf0,0x8d,0x16,0xaf,0x03,0xa9,0x07,0x75,0x17,0x01,0x8a,0x18,0x89}, 383 | 11, 384 | 0x1639, 385 | 0, 386 | {0x19,0xe4,0xf5,0x1a,0x75,0x1b,0x01,0xd3,0x22,0xc3,0x22}, 387 | 16, 388 | 0x15ec, 389 | 0, 390 | {0xa9,0x07,0xe5,0x1b,0x70,0x25,0x90,0x7f,0xa5,0xe0,0x44,0x80,0xf0,0xe9,0x25,0xe0}, 391 | 16, 392 | 0x15fc, 393 | 0, 394 | {0x44,0x01,0x90,0x7f,0xa6,0xf0,0x8d,0x16,0xaf,0x03,0xa9,0x07,0x75,0x17,0x01,0x8a}, 395 | 13, 396 | 0x160c, 397 | 0, 398 | {0x18,0x89,0x19,0xe4,0xf5,0x1a,0x75,0x1b,0x03,0xd3,0x22,0xc3,0x22}, 399 | 3, 400 | 0x4b, 401 | 0, 402 | {0x02,0x13,0x7f}, 403 | 16, 404 | 0x137f, 405 | 0, 406 | {0xc0,0xe0,0xc0,0x83,0xc0,0x82,0xc0,0x85,0xc0,0x84,0xc0,0x86,0x75,0x86,0x00,0xc0}, 407 | 16, 408 | 0x138f, 409 | 0, 410 | {0xd0,0x75,0xd0,0x00,0xc0,0x00,0xc0,0x01,0xc0,0x02,0xc0,0x03,0xc0,0x06,0xc0,0x07}, 411 | 16, 412 | 0x139f, 413 | 0, 414 | {0x90,0x7f,0xa5,0xe0,0x30,0xe2,0x06,0x75,0x1b,0x06,0x02,0x14,0x4e,0x90,0x7f,0xa5}, 415 | 16, 416 | 0x13af, 417 | 0, 418 | {0xe0,0x20,0xe1,0x0c,0xe5,0x1b,0x64,0x02,0x60,0x06,0x75,0x1b,0x07,0x02,0x14,0x4e}, 419 | 16, 420 | 0x13bf, 421 | 0, 422 | {0xaf,0x1b,0xef,0x24,0xfe,0x60,0x48,0x14,0x60,0x2c,0x24,0xfe,0x60,0x77,0x24,0x04}, 423 | 16, 424 | 0x13cf, 425 | 0, 426 | {0x60,0x03,0x02,0x14,0x4e,0xab,0x17,0xaa,0x18,0xa9,0x19,0xaf,0x1a,0x05,0x1a,0x8f}, 427 | 16, 428 | 0x13df, 429 | 0, 430 | {0x82,0x75,0x83,0x00,0x12,0x12,0x4b,0x90,0x7f,0xa6,0xf0,0xe5,0x1a,0x65,0x16,0x70}, 431 | 16, 432 | 0x13ef, 433 | 0, 434 | {0x5e,0x75,0x1b,0x05,0x80,0x59,0x90,0x7f,0xa6,0xe0,0xab,0x17,0xaa,0x18,0xa9,0x19}, 435 | 16, 436 | 0x13ff, 437 | 0, 438 | {0xae,0x1a,0x8e,0x82,0x75,0x83,0x00,0x12,0x12,0x78,0x75,0x1b,0x02,0x80,0x40,0xe5}, 439 | 16, 440 | 0x140f, 441 | 0, 442 | {0x16,0x24,0xfe,0xb5,0x1a,0x07,0x90,0x7f,0xa5,0xe0,0x44,0x20,0xf0,0xe5,0x16,0x14}, 443 | 16, 444 | 0x141f, 445 | 0, 446 | {0xb5,0x1a,0x0a,0x90,0x7f,0xa5,0xe0,0x44,0x40,0xf0,0x75,0x1b,0x00,0x90,0x7f,0xa6}, 447 | 16, 448 | 0x142f, 449 | 0, 450 | {0xe0,0xab,0x17,0xaa,0x18,0xa9,0x19,0xae,0x1a,0x8e,0x82,0x75,0x83,0x00,0x12,0x12}, 451 | 16, 452 | 0x143f, 453 | 0, 454 | {0x78,0x05,0x1a,0x80,0x0a,0x90,0x7f,0xa5,0xe0,0x44,0x40,0xf0,0x75,0x1b,0x00,0x53}, 455 | 16, 456 | 0x144f, 457 | 0, 458 | {0x91,0xdf,0xd0,0x07,0xd0,0x06,0xd0,0x03,0xd0,0x02,0xd0,0x01,0xd0,0x00,0xd0,0xd0}, 459 | 13, 460 | 0x145f, 461 | 0, 462 | {0xd0,0x86,0xd0,0x84,0xd0,0x85,0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32}, 463 | 16, 464 | 0x1704, 465 | 0, 466 | {0x12,0x15,0xec,0xe5,0x1b,0x24,0xfa,0x60,0x0e,0x14,0x60,0x06,0x24,0x07,0x70,0xf3}, 467 | 12, 468 | 0x1714, 469 | 0, 470 | {0xd3,0x22,0xe4,0xf5,0x1b,0xd3,0x22,0xe4,0xf5,0x1b,0xd3,0x22}, 471 | 16, 472 | 0x1720, 473 | 0, 474 | {0x12,0x16,0x19,0xe5,0x1b,0x24,0xfa,0x60,0x0e,0x14,0x60,0x06,0x24,0x07,0x70,0xf3}, 475 | 12, 476 | 0x1730, 477 | 0, 478 | {0xd3,0x22,0xe4,0xf5,0x1b,0xd3,0x22,0xe4,0xf5,0x1b,0xd3,0x22}, 479 | 16, 480 | 0x14ee, 481 | 0, 482 | {0x74,0x00,0xf5,0x86,0x90,0xfd,0xa5,0x7c,0x05,0xa3,0xe5,0x82,0x45,0x83,0x70,0xf9}, 483 | 1, 484 | 0x14fe, 485 | 0, 486 | {0x22}, 487 | 3, 488 | 0x0, 489 | 0, 490 | {0x02,0x17,0x53}, 491 | 12, 492 | 0x1753, 493 | 0, 494 | {0x78,0x7f,0xe4,0xf6,0xd8,0xfd,0x75,0x81,0x20,0x02,0x14,0x6c}, 495 | 16, 496 | 0x124b, 497 | 0, 498 | {0xbb,0x01,0x0c,0xe5,0x82,0x29,0xf5,0x82,0xe5,0x83,0x3a,0xf5,0x83,0xe0,0x22,0x50}, 499 | 16, 500 | 0x125b, 501 | 0, 502 | {0x06,0xe9,0x25,0x82,0xf8,0xe6,0x22,0xbb,0xfe,0x06,0xe9,0x25,0x82,0xf8,0xe2,0x22}, 503 | 13, 504 | 0x126b, 505 | 0, 506 | {0xe5,0x82,0x29,0xf5,0x82,0xe5,0x83,0x3a,0xf5,0x83,0xe4,0x93,0x22}, 507 | 16, 508 | 0x1278, 509 | 0, 510 | {0xf8,0xbb,0x01,0x0d,0xe5,0x82,0x29,0xf5,0x82,0xe5,0x83,0x3a,0xf5,0x83,0xe8,0xf0}, 511 | 16, 512 | 0x1288, 513 | 0, 514 | {0x22,0x50,0x06,0xe9,0x25,0x82,0xc8,0xf6,0x22,0xbb,0xfe,0x05,0xe9,0x25,0x82,0xc8}, 515 | 2, 516 | 0x1298, 517 | 0, 518 | {0xf2,0x22}, 519 | 16, 520 | 0x129a, 521 | 0, 522 | {0xe7,0x09,0xf6,0x08,0xdf,0xfa,0x80,0x46,0xe7,0x09,0xf2,0x08,0xdf,0xfa,0x80,0x3e}, 523 | 16, 524 | 0x12aa, 525 | 0, 526 | {0x88,0x82,0x8c,0x83,0xe7,0x09,0xf0,0xa3,0xdf,0xfa,0x80,0x32,0xe3,0x09,0xf6,0x08}, 527 | 16, 528 | 0x12ba, 529 | 0, 530 | {0xdf,0xfa,0x80,0x6e,0xe3,0x09,0xf2,0x08,0xdf,0xfa,0x80,0x66,0x88,0x82,0x8c,0x83}, 531 | 16, 532 | 0x12ca, 533 | 0, 534 | {0xe3,0x09,0xf0,0xa3,0xdf,0xfa,0x80,0x5a,0x89,0x82,0x8a,0x83,0xe0,0xa3,0xf6,0x08}, 535 | 16, 536 | 0x12da, 537 | 0, 538 | {0xdf,0xfa,0x80,0x4e,0x89,0x82,0x8a,0x83,0xe0,0xa3,0xf2,0x08,0xdf,0xfa,0x80,0x42}, 539 | 16, 540 | 0x12ea, 541 | 0, 542 | {0x80,0xd2,0x80,0xfa,0x80,0xc6,0x80,0xd4,0x80,0x55,0x80,0xf2,0x80,0x29,0x80,0x10}, 543 | 16, 544 | 0x12fa, 545 | 0, 546 | {0x80,0xa6,0x80,0xea,0x80,0x9a,0x80,0xa8,0x80,0xda,0x80,0xe2,0x80,0xca,0x80,0x29}, 547 | 16, 548 | 0x130a, 549 | 0, 550 | {0x88,0x84,0x8c,0x85,0x89,0x82,0x8a,0x83,0xe4,0x93,0xa3,0x05,0x86,0xf0,0xa3,0x05}, 551 | 16, 552 | 0x131a, 553 | 0, 554 | {0x86,0xdf,0xf5,0xde,0xf3,0x80,0x0b,0x89,0x82,0x8a,0x83,0xe4,0x93,0xa3,0xf6,0x08}, 555 | 16, 556 | 0x132a, 557 | 0, 558 | {0xdf,0xf9,0xec,0xfa,0xa9,0xf0,0xed,0xfb,0x22,0x88,0x84,0x8c,0x85,0x89,0x82,0x8a}, 559 | 16, 560 | 0x133a, 561 | 0, 562 | {0x83,0xe0,0xa3,0x05,0x86,0xf0,0xa3,0x05,0x86,0xdf,0xf6,0xde,0xf4,0x80,0xe3,0x89}, 563 | 16, 564 | 0x134a, 565 | 0, 566 | {0x82,0x8a,0x83,0xe4,0x93,0xa3,0xf2,0x08,0xdf,0xf9,0x80,0xd6,0x88,0xf0,0xed,0x24}, 567 | 16, 568 | 0x135a, 569 | 0, 570 | {0x02,0xb4,0x04,0x00,0x50,0xcc,0xf5,0x82,0xeb,0x24,0x02,0xb4,0x04,0x00,0x50,0xc2}, 571 | 16, 572 | 0x136a, 573 | 0, 574 | {0x23,0x23,0x45,0x82,0xf5,0x82,0xef,0x4e,0x60,0xb8,0xef,0x60,0x01,0x0e,0xe5,0x82}, 575 | 5, 576 | 0x137a, 577 | 0, 578 | {0x23,0x90,0x12,0xea,0x73}, 579 | 0, 580 | 0x0, 581 | 1, 582 | {0} 583 | }; 584 | -------------------------------------------------------------------------------- /src/intellikeysdefs.h: -------------------------------------------------------------------------------- 1 | // from https://github.com/gdsports/IntelliKeys_uhls 2 | 3 | #ifndef _INTELLIKEYSDEFS_H_ 4 | #define _INTELLIKEYSDEFS_H_ 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | enum IK_LEDS { 11 | IK_LED_SHIFT = 1, 12 | IK_LED_CAPS_LOCK = 4, 13 | IK_LED_MOUSE = 7, 14 | IK_LED_ALT = 2, 15 | IK_LED_CTRL_CMD = 5, 16 | IK_LED_NUM_LOCK = 8 17 | }; 18 | 19 | /* 20 | * Most of this file is extracted from the OpenIKeys project. 21 | */ 22 | 23 | #define IK_VID 0x095e 24 | #define IK_PID_FWLOAD 0x0100 // Firmware load required 25 | #define IK_PID_RUNNING 0x0101 // Firmware running 26 | 27 | #define IK_REPORT_LEN 8 28 | 29 | // resolution of the device 30 | #define IK_RESOLUTION_X 24 31 | #define IK_RESOLUTION_Y 24 32 | 33 | // number of switches 34 | #define IK_NUM_SWITCHES 6 35 | 36 | // number of sensors 37 | #define IK_NUM_SENSORS 3 38 | 39 | // 40 | // command codes sent to the device 41 | // see firmware documentation for details 42 | // 43 | 44 | #define CMD_BASE 0 45 | #define IK_CMD_GET_VERSION (CMD_BASE + 1) 46 | #define IK_CMD_LED (CMD_BASE + 2) 47 | #define IK_CMD_SCAN (CMD_BASE + 3) 48 | #define IK_CMD_TONE (CMD_BASE + 4) 49 | #define IK_CMD_GET_EVENT (CMD_BASE + 5) 50 | #define IK_CMD_INIT (CMD_BASE + 6) 51 | #define IK_CMD_EEPROM_READ (CMD_BASE + 7) 52 | #define IK_CMD_EEPROM_WRITE (CMD_BASE + 8) 53 | #define IK_CMD_ONOFFSWITCH (CMD_BASE + 9) 54 | #define IK_CMD_CORRECT (CMD_BASE + 10) 55 | #define IK_CMD_EEPROM_READBYTE (CMD_BASE + 11) 56 | #define IK_CMD_RESET_DEVICE (CMD_BASE + 12) 57 | #define IK_CMD_START_AUTO (CMD_BASE + 13) 58 | #define IK_CMD_STOP_AUTO (CMD_BASE + 14) 59 | #define IK_CMD_ALL_LEDS (CMD_BASE + 15) 60 | #define IK_CMD_START_OUTPUT (CMD_BASE + 16) 61 | #define IK_CMD_STOP_OUTPUT (CMD_BASE + 17) 62 | #define IK_CMD_ALL_SENSORS (CMD_BASE + 18) 63 | 64 | #define JWH 1 65 | 66 | #if JWH 67 | #define IK_CMD_REFLECT_KEYSTROKE \ 68 | (CMD_BASE + 21) // send keystroke to host via ezusb 69 | #define IK_CMD_REFLECT_MOUSE_MOVE \ 70 | (CMD_BASE + 22) // send mouse move to host via ezusb 71 | #endif 72 | 73 | #define IK_CMD_GET_SN CMD_BASE + 40 74 | 75 | // some internal commands that don't make it to the device 76 | #define COMMAND_BASE 100 // 0x64 77 | #define IK_CMD_DELAY (COMMAND_BASE + 1) // (msec) 78 | #define IK_CMD_MOUSE_MOVE (COMMAND_BASE + 2) // (x, y) 79 | #define IK_CMD_MOUSE_BUTTON (COMMAND_BASE + 3) // (left/right, down/up) 80 | #define IK_CMD_KEYBOARD (COMMAND_BASE + 4) // (keycode, down/up) 81 | #define IK_CMD_KEY_DONE \ 82 | (COMMAND_BASE + 5) // signal downstream that a key is done 83 | #define IK_CMD_KEY_START \ 84 | (COMMAND_BASE + 6) // signal downstream that a key is starting 85 | #define IK_CMD_KEY_REPEAT \ 86 | (COMMAND_BASE + 7) // signal downstream that a key is repeating 87 | 88 | #define IK_CMD_CP_HELP (COMMAND_BASE + 8) 89 | #define IK_CMD_CP_LIST_FEATURES (COMMAND_BASE + 9) 90 | #define IK_CMD_CP_REFRESH (COMMAND_BASE + 10) 91 | #define IK_CMD_CP_TOGGLE (COMMAND_BASE + 11) 92 | 93 | #define IK_CMD_KEYBOARD_UNICODE (COMMAND_BASE + 12) // lead, trail, down/up 94 | #define IK_CMD_LIFTALLMODIFIERS (COMMAND_BASE + 13) 95 | #define IK_CMD_CP_REPORT_REALTIME (COMMAND_BASE + 14) 96 | 97 | // 98 | // result codes/data sent to the software 99 | // see firmware documentation for details 100 | // 101 | #define EVENT_BASE 50 // 0x32 102 | #define IK_EVENT_ACK (EVENT_BASE + 1) 103 | #define IK_EVENT_MEMBRANE_PRESS (EVENT_BASE + 2) 104 | #define IK_EVENT_MEMBRANE_RELEASE (EVENT_BASE + 3) 105 | #define IK_EVENT_SWITCH (EVENT_BASE + 4) 106 | #define IK_EVENT_SENSOR_CHANGE (EVENT_BASE + 5) 107 | #define IK_EVENT_VERSION (EVENT_BASE + 6) 108 | #define IK_EVENT_EEPROM_READ (EVENT_BASE + 7) 109 | #define IK_EVENT_ONOFFSWITCH (EVENT_BASE + 8) 110 | #define IK_EVENT_NOMOREEVENTS (EVENT_BASE + 9) 111 | #define IK_EVENT_MEMBRANE_REPEAT (EVENT_BASE + 10) 112 | #define IK_EVENT_SWITCH_REPEAT (EVENT_BASE + 11) 113 | #define IK_EVENT_CORRECT_MEMBRANE (EVENT_BASE + 12) 114 | #define IK_EVENT_CORRECT_SWITCH (EVENT_BASE + 13) 115 | #define IK_EVENT_CORRECT_DONE (EVENT_BASE + 14) 116 | #define IK_EVENT_EEPROM_READBYTE (EVENT_BASE + 15) 117 | #define IK_EVENT_DEVICEREADY (EVENT_BASE + 16) 118 | #define IK_EVENT_AUTOPILOT_STATE (EVENT_BASE + 17) 119 | #define IK_EVENT_DELAY (EVENT_BASE + 18) 120 | #define IK_EVENT_ALL_SENSORS (EVENT_BASE + 19) 121 | 122 | #define IK_FIRSTUNUSED_EVENTCODE EVENT_BASE + 20 123 | 124 | // Arduino IK driver events 125 | #define AIK_EVENT_BASE 80 126 | #define IK_EVENT_CONNECT AIK_EVENT_BASE + 1 127 | #define IK_EVENT_DISCONNECT AIK_EVENT_BASE + 2 128 | #define IK_EVENT_SERNUM AIK_EVENT_BASE + 3 129 | 130 | // 131 | // number of light sensors for reading overlay bar codes 132 | // 133 | #define IK_MAX_SENSORS 3 134 | 135 | // 136 | // event reporting mode 137 | // auto = data sent to software without specific command 138 | // polled = data sent to software only when asked 139 | // 140 | #define IK_EVENT_MODE_AUTO 0 141 | #define IK_EVENT_MODE_POLLED 1 142 | 143 | // 144 | // Vendor specific request code for Anchor Upload/Download 145 | // 146 | // This one is implemented in the core 147 | // 148 | #define ANCHOR_LOAD_INTERNAL 0xA0 149 | #define ANCHOR_LOAD_EXTERNAL 0xA3 150 | 151 | // 152 | // This is the highest internal RAM address for the AN2131Q 153 | // 154 | #define MAX_INTERNAL_ADDRESS 0x1B3F 155 | 156 | #define INTERNAL_RAM(address) ((address <= MAX_INTERNAL_ADDRESS) ? true : false) 157 | 158 | // 159 | // EZ-USB Control and Status Register. Bit 0 controls 8051 reset 160 | // 161 | #define CPUCS_REG 0x7F92 162 | 163 | //--------------------------------------------------------------------+ 164 | // 165 | //--------------------------------------------------------------------+ 166 | 167 | #define MAX_INTEL_HEX_RECORD_LENGTH 16 168 | 169 | typedef struct _INTEL_HEX_RECORD { 170 | uint8_t Length; 171 | uint16_t Address; 172 | uint8_t Type; 173 | uint8_t Data[MAX_INTEL_HEX_RECORD_LENGTH]; 174 | } INTEL_HEX_RECORD, *PINTEL_HEX_RECORD; 175 | 176 | #define IK_EEPROM_SN_SIZE 29 177 | 178 | typedef struct { 179 | uint8_t serialnumber[IK_EEPROM_SN_SIZE]; 180 | uint8_t sensorBlack[IK_NUM_SENSORS]; 181 | uint8_t sensorWhite[IK_NUM_SENSORS]; 182 | } __attribute__((packed)) eeprom_t; 183 | 184 | #endif /* _INTELLIKEYSDEFS_H_ */ 185 | --------------------------------------------------------------------------------