diff --git a/.clang-tidy b/.clang-tidy new file mode 100644 index 0000000..8ae1316 --- /dev/null +++ b/.clang-tidy @@ -0,0 +1,16 @@ +--- +Checks: 'clang-diagnostic-*,clang-analyzer-*,-clang-analyzer-alpha*' +HeaderFilterRegex: '' +AnalyzeTemporaryDtors: false +User: hyatt +CheckOptions: + - key: google-readability-braces-around-statements.ShortStatementLines + value: '1' + - key: google-readability-function-size.StatementThreshold + value: '800' + - key: google-readability-namespace-comments.ShortNamespaceLines + value: '10' + - key: google-readability-namespace-comments.SpacesBeforeComments + value: '2' +... + diff --git a/.gitignore b/.gitignore index 7a86e68..574420d 100644 --- a/.gitignore +++ b/.gitignore @@ -56,6 +56,7 @@ tags CMakeFiles CMakeCache.txt cmake_install.cmake +compile_commands.json # External Repos # ################## diff --git a/98-kiibohd.rules b/98-kiibohd.rules index d00a8b2..3dccd01 100644 --- a/98-kiibohd.rules +++ b/98-kiibohd.rules @@ -2,18 +2,26 @@ ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789]?", ENV{ID_MM_DEVICE_IGNORE}="1" ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789]?", ENV{MTP_NO_PROBE}="1" SUBSYSTEMS=="usb", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789]?", MODE:="0666" + # Kiibohd Serial Interface -KERNEL=="ttyACM*", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789]?", MODE:="0666" -KERNEL=="ttyACM*", ATTRS{idVendor}=="1c11", ATTRS{idProduct}=="b04d", MODE:="0666" -KERNEL=="ttyACM*", ATTRS{idVendor}=="1c11", ATTRS{idProduct}=="f05c", MODE:="0666" +KERNEL=="ttyACM*", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789]?", SYMLINK+="kiibohd", MODE:="0666", +KERNEL=="ttyACM*", ATTRS{idVendor}=="1c11", ATTRS{idProduct}=="b04d", SYMLINK+="kiibohd", MODE:="0666" +KERNEL=="ttyACM*", ATTRS{idVendor}=="1c11", ATTRS{idProduct}=="f05c", SYMLINK+="kiibohd", MODE:="0666" + # Kiibohd Device SUBSYSTEMS=="usb", ATTRS{idVendor}=="1c11", ATTRS{idProduct}=="b04d", MODE:="0666" + # DFU Bootloader (MCHCK) ATTRS{idVendor}=="2323", ATTRS{idProduct}=="0001", ENV{ID_MM_DEVICE_IGNORE}="1" ATTRS{idVendor}=="2323", ATTRS{idProduct}=="0001", ENV{MTP_NO_PROBE}="1" SUBSYSTEMS=="usb", ATTRS{idVendor}=="2323", ATTRS{idProduct}=="0001", MODE:="0666" + # Kiibohd DFU Bootloader ATTRS{idVendor}=="1C11", ATTRS{idProduct}=="b007", ENV{ID_MM_DEVICE_IGNORE}="1" ATTRS{idVendor}=="1C11", ATTRS{idProduct}=="b007", ENV{MTP_NO_PROBE}="1" SUBSYSTEMS=="usb", ATTRS{idVendor}=="1c11", ATTRS{idProduct}=="b007", MODE:="0666" +# Kiibohd Force Gauge +SUBSYSTEM=="tty", ATTRS{idVendor}=="1c11", ATTRS{idProduct}=="f05c", GROUP="users", MODE="0666", SYMLINK+="force" +SUBSYSTEMS=="usb", ATTRS{idVendor}=="1c11", ATTRS{idProduct}=="f05c", MODE:="0666" + diff --git a/CMakeLists.txt b/CMakeLists.txt index dcb0c94..ec9fb62 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ ###| CMAKE Kiibohd Controller |### # -# Jacob Alexander 2011-2015 +# Jacob Alexander 2011-2016 # Due to this file's usefulness: # # Released into the Public Domain @@ -25,7 +25,8 @@ set( CHIP "mk20dx128vlf5" # McHCK mk20dx128vlf5 # "mk20dx256" # Teensy 3.1,3.2 (arm) # "mk20dx256vlh7" # Kiibohd-dfu mk20dx256vlh7 - CACHE STRING "Microcontroller Chip" ) + CACHE STRING "Microcontroller Chip" +) @@ -33,13 +34,14 @@ set( CHIP # Compiler Selection # -#| *** EXPERIMENTAL *** -#| Stick with gcc unless you know what you're doing +#| gcc has been tested much more (and will likely give smaller binaries) +#| clang does work though #| Currently only arm is supported with clang set( COMPILER "gcc" # arm-none-eabi-gcc / avr-gcc - Default # "clang" # arm-none-eabi - CACHE STRING "Compiler Type" ) + CACHE STRING "Compiler Type" +) @@ -72,11 +74,13 @@ set( MacroModule "PartialMap" ##| Sends the current list of usb key codes through USB HID set( OutputModule "pjrcUSB" - CACHE STRING "Output Module" ) + CACHE STRING "Output Module" +) ##| Debugging source to use, each module has it's own set of defines that it sets set( DebugModule "full" - CACHE STRING "Debug Module" ) + CACHE STRING "Debug Module" +) diff --git a/Lib/CMake/arm.cmake b/Lib/CMake/arm.cmake index be04de2..31fe0cd 100644 --- a/Lib/CMake/arm.cmake +++ b/Lib/CMake/arm.cmake @@ -1,6 +1,6 @@ ###| CMAKE Kiibohd Controller |### # -# Jacob Alexander 2011-2014 +# Jacob Alexander 2011-2016 # Due to this file's usefulness: # # Released into the Public Domain @@ -111,6 +111,13 @@ set( COMPILER_SRCS Lib/delay.c ) +#| Clang needs a few more functions for linking +if ( "${COMPILER}" MATCHES "clang" ) + set( COMPILER_SRCS ${COMPILER_SRCS} + Lib/clang.c + ) +endif () + message( STATUS "Compiler Source Files:" ) message( "${COMPILER_SRCS}" ) diff --git a/Lib/CMake/build.cmake b/Lib/CMake/build.cmake index 4cdf8b8..a3aa211 100644 --- a/Lib/CMake/build.cmake +++ b/Lib/CMake/build.cmake @@ -135,3 +135,23 @@ elseif ( DEFINED TEENSY ) endif() endif() + + +### +# Compiler Command Generation +# + +#| Generate list of compiler commands for clang-tidy usage +set( CMAKE_EXPORT_COMPILE_COMMANDS ON ) + +#| Make sure symlink exists (for convenience) +if ( UNIX ) + # Make sure symlink is created immediately + execute_process ( COMMAND ln -sfn ${CMAKE_BINARY_DIR}/compile_commands.json ${CMAKE_SOURCE_DIR}/. ) + + # Also update before each build + add_custom_command( TARGET ${TARGET_ELF} POST_BUILD + COMMAND ln -sfn ${CMAKE_BINARY_DIR}/compile_commands.json ${CMAKE_SOURCE_DIR}/. + ) +endif () + diff --git a/Lib/clang.c b/Lib/clang.c new file mode 100644 index 0000000..f502409 --- /dev/null +++ b/Lib/clang.c @@ -0,0 +1,61 @@ +/* Copyright (C) 2016 by Jacob Alexander + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + + +// This file adds various functions that clang doesn't link properly +// AFAIK, clang doesn't have an elegant solution for this, so this is what we gotta do... + +// ----- Includes ----- + +// Compiler Includes +#include + + +void __aeabi_memcpy( void *dest, const void *src, size_t n ) +{ + (void)memcpy(dest, src, n); +} + +void __aeabi_memcpy4( void *dest, const void *src, size_t n ) +{ + memcpy(dest, src, n); +} + +void __aeabi_memclr( void *dest, size_t n ) +{ + memset(dest, 0, n); +} + +void __aeabi_memclr4( void *dest, size_t n ) +{ + memset(dest, 0, n); +} + +void __aeabi_memmove( void *dest, const void *src, size_t n ) +{ + (void)memmove(dest, src, n); +} + +void __aeabi_memset( void *s, size_t n, int c ) +{ + (void)memset(s, c, n); +} + diff --git a/Output/pjrcUSB/arm/usb_desc.c b/Output/pjrcUSB/arm/usb_desc.c index 1d9a939..b0be2a0 100644 --- a/Output/pjrcUSB/arm/usb_desc.c +++ b/Output/pjrcUSB/arm/usb_desc.c @@ -309,37 +309,33 @@ static uint8_t sys_ctrl_report_desc[] = { static uint8_t mouse_report_desc[] = { 0x05, 0x01, // Usage Page (Generic Desktop) 0x09, 0x02, // Usage (Mouse) - 0xa1, 0x01, // Collection (Application) + 0xA1, 0x01, // Collection (Application) 0x09, 0x02, // Usage (Mouse) - 0xa1, 0x02, // Collection (Logical) + 0xA1, 0x02, // Collection (Logical) 0x09, 0x01, // Usage (Pointer) - // Buttons (5 bits) - 0xa1, 0x00, // Collection (Physical) - Buttons + // Buttons (16 bits) + 0xA1, 0x00, // Collection (Physical) - Buttons 0x05, 0x09, // Usage Page (Button) 0x19, 0x01, // Usage Minimum (Button 1) - 0x29, 0x05, // Usage Maximum (Button 5) + 0x29, 0x10, // Usage Maximum (Button 16) 0x15, 0x00, // Logical Minimum (0) 0x25, 0x01, // Logical Maximum (1) 0x75, 0x01, // Report Size (1) - 0x95, 0x05, // Report Count (5) + 0x95, 0x10, // Report Count (16) 0x81, 0x02, // Input (Data,Var,Abs) - // Padding (3 bits) - 0x75, 0x03, // Report Size (3) - 0x95, 0x01, // Report Count (1) - 0x81, 0x03, // Input (Cnst,Var,Abs) - - // Pointer (16 bits) + // Pointer (32 bits) 0x05, 0x01, // Usage PAGE (Generic Desktop) 0x09, 0x30, // Usage (X) 0x09, 0x31, // Usage (Y) - 0x15, 0x81, // Logical Minimum (-127) - 0x25, 0x7f, // Logical Maximum (127) - 0x75, 0x08, // Report Size (8) + 0x16, 0x01, 0x80, // Logical Minimum (-32 767) + 0x26, 0xFF, 0x7F, // Logical Maximum (32 767) + 0x75, 0x10, // Report Size (16) 0x95, 0x02, // Report Count (2) 0x81, 0x06, // Input (Data,Var,Rel) + /* // Vertical Wheel // - Multiplier (2 bits) 0xa1, 0x02, // Collection (Logical) @@ -382,6 +378,7 @@ static uint8_t mouse_report_desc[] = { 0x81, 0x06, // Input (Data,Var,Rel) 0xc0, // End Collection - Horizontal Wheel + */ 0xc0, // End Collection - Buttons 0xc0, // End Collection - Mouse Logical 0xc0 // End Collection - Mouse Application diff --git a/Output/pjrcUSB/arm/usb_mouse.c b/Output/pjrcUSB/arm/usb_mouse.c index 2b1dc72..5de7712 100644 --- a/Output/pjrcUSB/arm/usb_mouse.c +++ b/Output/pjrcUSB/arm/usb_mouse.c @@ -1,7 +1,7 @@ /* Teensyduino Core Library * http://www.pjrc.com/teensy/ * Copyright (c) 2013 PJRC.COM, LLC. - * Modified by Jacob Alexander (2015) + * Modified by Jacob Alexander (2015-2016) * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the @@ -115,38 +115,78 @@ // ----- Variables ----- -// which buttons are currently pressed -uint8_t usb_mouse_buttons_state=0; +static uint8_t transmit_previous_timeout = 0; -static uint16_t usb_mouse_resolution_x=DEFAULT_XRES; -static uint16_t usb_mouse_resolution_y=DEFAULT_YRES; -static uint16_t usb_mouse_position_x=DEFAULT_XRES/2; -static uint16_t usb_mouse_position_y=DEFAULT_YRES/2; -static uint32_t usb_mouse_scale_x=DEFAULT_XSCALE; -static uint32_t usb_mouse_scale_y=DEFAULT_YSCALE; -static uint32_t usb_mouse_offset_x=DEFAULT_XSCALE/2-1; -static uint32_t usb_mouse_offset_y=DEFAULT_YSCALE/2-1; +// which buttons are currently pressed +uint8_t usb_mouse_buttons_state = 0; + +static uint16_t usb_mouse_resolution_x = DEFAULT_XRES; +static uint16_t usb_mouse_resolution_y = DEFAULT_YRES; +static uint16_t usb_mouse_position_x = DEFAULT_XRES / 2; +static uint16_t usb_mouse_position_y = DEFAULT_YRES / 2; +static uint32_t usb_mouse_scale_x = DEFAULT_XSCALE; +static uint32_t usb_mouse_scale_y = DEFAULT_YSCALE; +static uint32_t usb_mouse_offset_x = DEFAULT_XSCALE / 2 - 1; +static uint32_t usb_mouse_offset_y = DEFAULT_YSCALE / 2 - 1; // ----- Functions ----- -// Set the mouse buttons. To create a "click", 2 calls are needed, -// one to push the button down and the second to release it -int usb_mouse_buttons(uint8_t left, uint8_t middle, uint8_t right) +// Process pending mouse commands +// XXX Missing mouse movement and wheels +// Proper support will require KLL generation of the USB descriptors +// Similar support will be required for joystick control +void usb_mouse_send() { - uint8_t mask=0; + uint32_t wait_count = 0; + usb_packet_t *tx_packet; - if (left) mask |= 1; - if (middle) mask |= 4; - if (right) mask |= 2; - usb_mouse_buttons_state = mask; - return usb_mouse_move(0, 0, 0); + // Wait till ready + while ( 1 ) + { + if ( !usb_configuration ) + { + erro_print("USB not configured..."); + return; + } + + // Attempt to acquire a USB packet for the mouse endpoint + if ( usb_tx_packet_count( MOUSE_ENDPOINT ) < TX_PACKET_LIMIT ) + { + tx_packet = usb_malloc(); + if ( tx_packet ) + break; + } + + if ( ++wait_count > TX_TIMEOUT || transmit_previous_timeout ) + { + transmit_previous_timeout = 1; + warn_print("USB Transmit Timeout..."); + return; + } + yield(); + } + + transmit_previous_timeout = 0; + + // Prepare USB Mouse Packet + // TODO Dynamically generate this code based on KLL requirements + uint16_t *packet_data = (uint16_t*)(&tx_packet->buf[0]); + packet_data[0] = USBMouse_Buttons; + packet_data[1] = USBMouse_Relative_x; + packet_data[2] = USBMouse_Relative_y; + tx_packet->len = 6; + usb_tx( MOUSE_ENDPOINT, tx_packet ); + + // Clear status and state + USBMouse_Buttons = 0; + USBMouse_Relative_x = 0; + USBMouse_Relative_y = 0; + USBMouse_Changed = 0; } -static uint8_t transmit_previous_timeout=0; - // Move the mouse. x, y and wheel are -127 to 127. Use 0 for no movement. int usb_mouse_move(int8_t x, int8_t y, int8_t wheel) { diff --git a/Output/pjrcUSB/arm/usb_mouse.h b/Output/pjrcUSB/arm/usb_mouse.h index ffa9fe2..397d967 100644 --- a/Output/pjrcUSB/arm/usb_mouse.h +++ b/Output/pjrcUSB/arm/usb_mouse.h @@ -1,7 +1,7 @@ /* Teensyduino Core Library * http://www.pjrc.com/teensy/ * Copyright (c) 2013 PJRC.COM, LLC. - * Modified by Jacob Alexander (2015) + * Modified by Jacob Alexander (2015-2016) * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the @@ -43,16 +43,11 @@ // ----- Functions ----- +// Proces pending mouse commands +void usb_mouse_send(); + // TODO - More generic -int usb_mouse_buttons( uint8_t left, uint8_t middle, uint8_t right ); int usb_mouse_move( int8_t x, int8_t y, int8_t wheel ); int usb_mouse_position( uint16_t x, uint16_t y ); void usb_mouse_screen_size( uint16_t width, uint16_t height, uint8_t mac ); -extern uint8_t usb_mouse_buttons_state; - -// TODO - Move -#define MOUSE_LEFT 1 -#define MOUSE_MIDDLE 4 -#define MOUSE_RIGHT 2 -#define MOUSE_ALL (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE) diff --git a/Output/pjrcUSB/capabilities.kll b/Output/pjrcUSB/capabilities.kll index 7646625..c83f910 100644 --- a/Output/pjrcUSB/capabilities.kll +++ b/Output/pjrcUSB/capabilities.kll @@ -1,10 +1,10 @@ Name = pjrcUSBCapabilities; -Version = 0.6; -Author = "HaaTa (Jacob Alexander) 2014-2015"; -KLL = 0.3c; +Version = 0.8; +Author = "HaaTa (Jacob Alexander) 2014-2016"; +KLL = 0.3d; # Modified Date -Date = 2015-08-21; +Date = 2016-03-21; # Output capabilities @@ -12,6 +12,7 @@ consCtrlOut => Output_consCtrlSend_capability( consCode : 2 ); noneOut => Output_noneSend_capability(); sysCtrlOut => Output_sysCtrlSend_capability( sysCode : 1 ); usbKeyOut => Output_usbCodeSend_capability( usbCode : 1 ); +mouseOut => Output_usbMouse_capability( mouseCode : 2, relative_x : 2, relative_y : 2 ); # Configuration capabilities kbdProtocolBoot => Output_kbdProtocolBoot_capability(); @@ -21,6 +22,12 @@ kbdProtocolNKRO => Output_kbdProtocolNKRO_capability(); keyboardLocale => KeyboardLocale_define; keyboardLocale = 0; +# Default KRO Mode +# Set to 0 for Boot Mode (6KRO) +# Set to 1 for NKRO Mode (default) +usbProtocol => USBProtocol_define; +usbProtocol = 1; + # Bootloader Mode capability # XXX # By default this is disabled on purpose diff --git a/Output/pjrcUSB/output_com.c b/Output/pjrcUSB/output_com.c index b18bbdb..39ee0b0 100644 --- a/Output/pjrcUSB/output_com.c +++ b/Output/pjrcUSB/output_com.c @@ -37,8 +37,12 @@ #include "arm/usb_dev.h" #include "arm/usb_keyboard.h" #include "arm/usb_serial.h" +#include "arm/usb_mouse.h" #endif +// KLL +#include + // Local Includes #include "output_com.h" @@ -47,14 +51,15 @@ // ----- Macros ----- // Used to build a bitmap lookup table from a byte addressable array -#define byteLookup( byte ) case (( byte ) * ( 8 )): bytePosition = byte; byteShift = 0; break; \ - case (( byte ) * ( 8 ) + ( 1 )): bytePosition = byte; byteShift = 1; break; \ - case (( byte ) * ( 8 ) + ( 2 )): bytePosition = byte; byteShift = 2; break; \ - case (( byte ) * ( 8 ) + ( 3 )): bytePosition = byte; byteShift = 3; break; \ - case (( byte ) * ( 8 ) + ( 4 )): bytePosition = byte; byteShift = 4; break; \ - case (( byte ) * ( 8 ) + ( 5 )): bytePosition = byte; byteShift = 5; break; \ - case (( byte ) * ( 8 ) + ( 6 )): bytePosition = byte; byteShift = 6; break; \ - case (( byte ) * ( 8 ) + ( 7 )): bytePosition = byte; byteShift = 7; break +#define byteLookup( byte ) \ + case (( byte ) * ( 8 )): bytePosition = byte; byteShift = 0; break; \ + case (( byte ) * ( 8 ) + ( 1 )): bytePosition = byte; byteShift = 1; break; \ + case (( byte ) * ( 8 ) + ( 2 )): bytePosition = byte; byteShift = 2; break; \ + case (( byte ) * ( 8 ) + ( 3 )): bytePosition = byte; byteShift = 3; break; \ + case (( byte ) * ( 8 ) + ( 4 )): bytePosition = byte; byteShift = 4; break; \ + case (( byte ) * ( 8 ) + ( 5 )): bytePosition = byte; byteShift = 5; break; \ + case (( byte ) * ( 8 ) + ( 6 )): bytePosition = byte; byteShift = 6; break; \ + case (( byte ) * ( 8 ) + ( 7 )): bytePosition = byte; byteShift = 7; break @@ -111,15 +116,25 @@ uint8_t USBKeys_SentCLI = 0; // 1=num lock, 2=caps lock, 4=scroll lock, 8=compose, 16=kana volatile uint8_t USBKeys_LEDs = 0; +// Currently pressed mouse buttons, bitmask, 0 represents no buttons pressed +volatile uint16_t USBMouse_Buttons = 0; + +// Relative mouse axis movement, stores pending movement +volatile uint16_t USBMouse_Relative_x = 0; +volatile uint16_t USBMouse_Relative_y = 0; + // Protocol setting from the host. // 0 - Boot Mode // 1 - NKRO Mode (Default, unless set by a BIOS or boot interface) -volatile uint8_t USBKeys_Protocol = 1; +volatile uint8_t USBKeys_Protocol = USBProtocol_define; // Indicate if USB should send update // OS only needs update if there has been a change in state USBKeyChangeState USBKeys_Changed = USBKeyChangeState_None; +// Indicate if USB should send update +USBMouseChangeState USBMouse_Changed = 0; + // the idle configuration, how often we send the report to the // host (ms * 4) even when it hasn't changed uint8_t USBKeys_Idle_Config = 125; @@ -505,6 +520,63 @@ void Output_flashMode_capability( uint8_t state, uint8_t stateType, uint8_t *arg Output_firmwareReload(); } +// Sends a mouse command over the USB Output buffer +// XXX This function *will* be changing in the future +// If you use it, be prepared that your .kll files will break in the future (post KLL 0.5) +// Argument #1: USB Mouse Button (16 bit) +// Argument #2: USB X Axis (16 bit) relative +// Argument #3: USB Y Axis (16 bit) relative +void Output_usbMouse_capability( uint8_t state, uint8_t stateType, uint8_t *args ) +{ + // Display capability name + if ( stateType == 0xFF && state == 0xFF ) + { + print("Output_usbMouse(mouseButton,relX,relY)"); + return; + } + + // Determine which mouse button was sent + // The USB spec defines up to a max of 0xFFFF buttons + // The usual are: + // 1 - Button 1 - (Primary) + // 2 - Button 2 - (Secondary) + // 3 - Button 3 - (Tertiary) + uint16_t mouse_button = *(uint16_t*)(&args[0]); + + // X/Y Relative Axis + uint16_t mouse_x = *(uint16_t*)(&args[2]); + uint16_t mouse_y = *(uint16_t*)(&args[4]); + + // Adjust for bit shift + uint16_t mouse_button_shift = mouse_button - 1; + + // Only send mouse button if in press or hold state + if ( stateType == 0x00 && state == 0x03 ) // Release state + { + // Release + if ( mouse_button ) + USBMouse_Buttons &= ~(1 << mouse_button_shift); + } + else + { + // Press or hold + if ( mouse_button ) + USBMouse_Buttons |= (1 << mouse_button_shift); + + if ( mouse_x ) + USBMouse_Relative_x = mouse_x; + if ( mouse_y ) + USBMouse_Relative_y = mouse_y; + } + + // Trigger updates + if ( mouse_button ) + USBMouse_Changed |= USBMouseChangeState_Buttons; + + if ( mouse_x || mouse_y ) + USBMouse_Changed |= USBMouseChangeState_Relative; +} + // ----- Functions ----- @@ -552,6 +624,10 @@ inline void Output_send() for ( uint8_t c = USBKeys_Sent; c < USB_BOOT_MAX_KEYS; c++ ) USBKeys_Keys[c] = 0; + // Process mouse actions + while ( USBMouse_Changed ) + usb_mouse_send(); + // Send keypresses while there are pending changes while ( USBKeys_Changed ) usb_keyboard_send(); diff --git a/Output/pjrcUSB/output_com.h b/Output/pjrcUSB/output_com.h index 2448683..36369eb 100644 --- a/Output/pjrcUSB/output_com.h +++ b/Output/pjrcUSB/output_com.h @@ -56,6 +56,14 @@ typedef enum USBKeyChangeState { USBKeyChangeState_All = 0x7F, } USBKeyChangeState; +// Allows for selective USB descriptor pushes +// However, in most cases everything is updated for each packet push +typedef enum USBMouseChangeState { + USBMouseChangeState_None = 0x00, + USBMouseChangeState_Buttons = 0x01, + USBMouseChangeState_Relative = 0x02, +} USBMouseChangeState; + // ----- Variables ----- @@ -72,11 +80,16 @@ extern uint16_t USBKeys_ConsCtrl; // 1KRO container for Consumer Contro extern volatile uint8_t USBKeys_Protocol; // 0 - Boot Mode, 1 - NKRO Mode +extern volatile uint16_t USBMouse_Buttons; // Bitmask for mouse buttons +extern volatile uint16_t USBMouse_Relative_x; +extern volatile uint16_t USBMouse_Relative_y; + // Misc variables (XXX Some are only properly utilized using AVR) extern uint8_t USBKeys_Idle_Config; extern uint8_t USBKeys_Idle_Count; -extern USBKeyChangeState USBKeys_Changed; +extern USBKeyChangeState USBKeys_Changed; +extern USBMouseChangeState USBMouse_Changed; extern volatile uint8_t Output_Available; // 0 - Output module not fully functional, 1 - Output module working diff --git a/Scan/CK3/defaultMap.kll b/Scan/CK3/defaultMap.kll index d821d95..30de5d0 100644 --- a/Scan/CK3/defaultMap.kll +++ b/Scan/CK3/defaultMap.kll @@ -1,85 +1,132 @@ Name = CK3; Version = 0.3; Author = "Crystal Hammer 2016"; -KLL = 0.3c; +KLL = 0.3d; # Modified Date -Date = 2016-02-19; +Date = 2016-03-01; + +# this is nearly the default map + +S0x0F : U"Esc"; +S0x8C : U"F1"; +S0x8B : U"F2"; +S0x67 : U"F3"; +S0x0D : U"F4"; +S0x6E : U"F5"; +S0x06 : U"F6"; +S0x5F : U"F7"; +S0x83 : U"F8"; +S0x7F : U"F9"; +S0x6D : U"F10"; +S0x01 : U"F11"; +S0x13 : U"F12"; +S0x6F : U"PrintScreen"; +S0x4B : U"ScrollLock"; +S0x4A : U"Pause"; +S0x39 : U"F16"; + +S0x8D : U"BackTick"; +S0x7B : U"1"; +S0x7A : U"2"; +S0x79 : U"3"; +S0x74 : U"4"; +S0x86 : U"5"; +S0x85 : U"6"; +S0x73 : U"7"; +S0x72 : U"8"; +S0x71 : U"9"; +S0x6C : U"0"; +S0x7E : U"-"; +S0x84 : U"="; +S0x5B : U"Backspace"; -S0x00 : U"Esc"; -S0x01 : U"1"; -S0x02 : U"2"; -S0x03 : U"3"; -S0x04 : U"4"; -S0x05 : U"5"; -S0x06 : U"6"; -S0x07 : U"7"; -S0x08 : U"8"; -S0x09 : U"9"; -S0x0A : U"0"; -S0x0B : U"Minus"; -S0x0C : U"Equal"; -S0x0D : U"Backslash"; -S0x0E : U"Backtick"; -S0x0F : U"Tab"; -S0x10 : U"Q"; -S0x11 : U"W"; -S0x12 : U"E"; -S0x13 : U"R"; -S0x14 : U"T"; -S0x15 : U"Y"; -S0x16 : U"U"; -S0x17 : U"I"; -S0x18 : U"O"; -S0x19 : U"P"; -S0x1A : U"LBrace"; -S0x1B : U"RBrace"; -S0x1C : U"Backspace"; -S0x1D : U"Ctrl"; -S0x1E : U"A"; -S0x1F : U"S"; -S0x20 : U"D"; -S0x21 : U"F"; -S0x22 : U"G"; -S0x23 : U"H"; -S0x24 : U"J"; -S0x25 : U"K"; -S0x26 : U"L"; -S0x27 : U"Semicolon"; -S0x28 : U"Quote"; -S0x29 : U"Enter"; -S0x2A : U"LShift"; -S0x2B : U"Z"; -S0x2C : U"X"; -S0x2D : U"C"; -S0x2E : U"V"; -S0x2F : U"B"; -S0x30 : U"N"; -S0x31 : U"M"; -S0x32 : U"Comma"; -S0x33 : U"Period"; -S0x34 : U"Slash"; -S0x35 : U"RShift"; -S0x36 : U"Function1"; # Fun key -S0x37 : U"Function2"; # Left Blank Key -S0x38 : U"LAlt"; -S0x39 : U"LGui"; -S0x3A : U"Space"; -S0x3B : U"RGui"; -S0x3C : U"RAlt"; -S0x3D : U"Function3"; # Right Blank Key 1 -S0x3E : U"Function4"; # Right Blank Key 2 +S0x69 : U"Tab"; +S0x57 : U"Q"; +S0x56 : U"W"; +S0x55 : U"E"; +S0x50 : U"R"; +S0x62 : U"T"; +S0x61 : U"Y"; +S0x4F : U"U"; +S0x4E : U"I"; +S0x4D : U"O"; +S0x48 : U"P"; +S0x5A : U"["; +S0x60 : U"]"; +S0x37 : U"\"; +S0x68 : U"CapsLock"; +S0x45 : U"A"; +S0x44 : U"S"; +S0x43 : U"D"; +S0x3E : U"F"; +S0x08 : U"G"; +S0x07 : U"H"; +S0x3D : U"J"; +S0x3C : U"K"; +S0x3B : U"L"; +S0x36 : U";"; +S0x00 : U"'"; +S0x25 : U"Enter"; -# Custom Action Examples +S0x5E : U"LShift"; +S0x33 : U"Z"; +S0x32 : U"X"; +S0x31 : U"C"; +S0x2C : U"V"; +S0x1A : U"B"; +S0x19 : U"N"; +S0x2B : U"M"; +S0x2A : U","; +S0x29 : U"."; +S0x12 : U"/"; +S0x3A : U"RShift"; -# Example capability, prints to cli -action1 => CustomAction_action1_capability(); # No arguments +# bottom +S0x80 : U"LCtrl"; +S0x6A : U"LGui"; +S0x0E : U"LAlt"; +S0x03 : U"LAlt"; +S0x09 : U"Space"; +S0x15 : U"RAlt"; +S0x17 : U"RGui"; +S0x88 : U"RCtrl"; +S0x87 : U"RCtrl"; -# Blocks given USB Code, must be used with blockLink -# Simple example, supports only blocking a single key at a time -# Keys must be specified using numbers see Macro/PartialMap/usb_hid.h -blockHold => CustomAction_blockHold_capability( usbCode : 1 ); # Single 8-bit argument -blockKey => CustomAction_blockKey_capability( usbCode : 1 ); +# middle right column, custom +S0x8A : U"Esc"; +S0x89 : U"Backspace"; +S0x77 : U"Enter"; +S0x78 : U"RShift"; +# arrows +S0x1E : U"Left"; +S0x0C : U"Up"; +S0x1B : U"Down"; +S0x1C : U"Right"; +# S0x1C : U"RCtrl"; + +# numpad +S0x2D : U"NumLock"; +S0x2E : U"P/"; +S0x2F : U"P*"; +S0x1D : U"P-"; + +S0x51 : U"P7"; +S0x52 : U"P8"; +S0x53 : U"P9"; +S0x54 : U"P+"; + +S0x63 : U"P4"; +S0x64 : U"P5"; +S0x65 : U"P6"; + +S0x3F : U"P1"; +S0x40 : U"P2"; +S0x41 : U"P3"; +S0x42 : U"PEnter"; + +S0x0A : U"P0"; +S0x0B : U"P."; diff --git a/Scan/CK3/matrix.h b/Scan/CK3/matrix.h index 1a2be2e..7f6632d 100644 --- a/Scan/CK3/matrix.h +++ b/Scan/CK3/matrix.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2014-2015 by Jacob Alexander +/* Copyright (C) 2014-2016 by Jacob Alexander, Crystal Hammer * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -27,28 +27,42 @@ #include - // ----- Matrix Definition ----- +// CK3 +// Columns (Strobe) 18 +// Rows (Sense) 8 -// Freescale ARM MK20's support GPIO PTA, PTB, PTC, PTD and PTE 0..31 -// Not all chips have access to all of these pins (most don't have 160 pins :P) -// -// NOTE: -// Before using a pin, make sure it supports being a GPIO *and* doesn't have a default pull-up/pull-down -// Checking this is completely on the ownness of the user +// This is the default map of just A4Tech KX-100 matrix +// scan codes for keys are defined in defaultMap.kll +/* + 1| 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 + - + 1 Mcmp Bstp Esc \ F4 Up Del Ins Spc G H F6 == Vol- AltL xx F11 ' + 2 Calc ExA4 ExC2 ExE2 ExE1 <- Sub -> Dn B N ExC1 Apps Mnxt AltR xx F12 / + 3 Mstp Bbck Z X C Mpau Mul Div NumL V M , . Vol+ xx CtrR Ent \ + 4 GuiR Bfwd A S D Ent PgDn Dn End F J K L ShiR xx == \ ; + 5 xx Mail Q W E Add PgUp Up Home R U I O xx ScrL Paus ExE3 P + 6 ExB1 GuiL Tab Caps F3 RB~ -> Del <- T Y ] F7 ShiL == Pwr Back [ + 7 xx Bsch 1 2 3 End PgDn xx Pwr 4 7 8 9 Msel Ptr F5 F10 0 + 8 Bhom Vmut `~ F1 F2 Home PgUp Ins Del 5 6 = F8 Mprv == CtrL F9 - -// -// Columns (Strobe) // PTB0..3,16,17 PTC4,5 PTD0 -// Rows (Sense) // PTD1..7 - -// Define Rows (Sense) and Columns (Strobes) -GPIO_Pin Matrix_cols[] = { gpio(B,0), gpio(B,1), gpio(B,2), gpio(B,3), gpio(B,16), gpio(B,17), gpio(C,4), gpio(C,6), gpio(D,0) }; -GPIO_Pin Matrix_rows[] = { gpio(D,1), gpio(D,2), gpio(D,3), gpio(D,4), gpio(D,5), gpio(D,6), gpio(D,7) }; + rows - columns | + 1 3 5 7 1 3 5 7 9 11 13 15 17 + 2 4 6 8 2 4 6 8 10 12 14 16 18 connectors, PCB view +*/ +GPIO_Pin Matrix_cols[] = { + gpio(B,16), gpio(B,17), gpio(D,0), gpio(A,12), gpio(A,13), gpio(D,7), gpio(D,4), gpio(D,2), gpio(D,3), + gpio(C,2), gpio(C,1), gpio(D,6), gpio(D,5), gpio(B,2), gpio(B,3), gpio(B,1), gpio(B,0), gpio(C,0) }; +GPIO_Pin Matrix_rows[] = { + gpio(C,10), gpio(C,11), gpio(B,18), gpio(A,4), gpio(A,5), gpio(B,19), gpio(C,9), gpio(C,8) }; // Define type of scan matrix -Config Matrix_type = Config_Pulldown; +Config Matrix_type = Config_Pullup; // Define this if your matrix has ghosting (i.e. regular keyboard without diodes) // this will enable the anti-ghosting code #define GHOSTING_MATRIX + +// delay in microseconds before and after each strobe change during matrix scan +#define STROBE_DELAY 10 diff --git a/Scan/CK3/scan_loop.c b/Scan/CK3/scan_loop.c index 22d43c2..b4c8c99 100644 --- a/Scan/CK3/scan_loop.c +++ b/Scan/CK3/scan_loop.c @@ -175,6 +175,15 @@ void CustomAction_blockKey_capability( uint8_t state, uint8_t stateType, uint8_t } +// Signal from the Output Module that the available current has changed +// current - mA +void Scan_currentChange( unsigned int current ) +{ + // Indicate to all submodules current change + Matrix_currentChange( current ); +} + + // ----- CLI Command Functions ----- diff --git a/Scan/CK3/scan_loop.h b/Scan/CK3/scan_loop.h index 0c89838..3c543ea 100644 --- a/Scan/CK3/scan_loop.h +++ b/Scan/CK3/scan_loop.h @@ -38,6 +38,8 @@ uint8_t Scan_loop( void ); void Scan_finishedWithMacro( uint8_t sentKeys ); // Called by Macro Module void Scan_finishedWithOutput( uint8_t sentKeys ); // Called by Output Module +void Scan_currentChange( unsigned int current ); // Called by Output Module + // ----- Capabilities ----- diff --git a/Scan/ISSILed/led_scan.h b/Scan/ISSILed/led_scan.h index 7352e72..75d7937 100644 --- a/Scan/ISSILed/led_scan.h +++ b/Scan/ISSILed/led_scan.h @@ -36,3 +36,5 @@ void LED_scan(); void LED_currentChange( unsigned int current ); +void LED_currentChange( unsigned int current ); + diff --git a/Scan/MatrixARM/matrix_scan.c b/Scan/MatrixARM/matrix_scan.c index 017161d..cbb0e76 100644 --- a/Scan/MatrixARM/matrix_scan.c +++ b/Scan/MatrixARM/matrix_scan.c @@ -30,6 +30,7 @@ #include #include #include +#include // Local Includes #include "matrix_scan.h" @@ -51,6 +52,7 @@ nat_ptr_t Matrix_divCounter = 0; // CLI Functions void cliFunc_matrixDebug( char* args ); +void cliFunc_matrixInfo( char* args ); void cliFunc_matrixState( char* args ); @@ -59,10 +61,12 @@ void cliFunc_matrixState( char* args ); // Scan Module command dictionary CLIDict_Entry( matrixDebug, "Enables matrix debug mode, prints out each scan code." NL "\t\tIf argument \033[35mT\033[0m is given, prints out each scan code state transition." ); +CLIDict_Entry( matrixInfo, "Print info about the configured matrix." ); CLIDict_Entry( matrixState, "Prints out the current scan table N times." NL "\t\t \033[1mO\033[0m - Off, \033[1;33mP\033[0m - Press, \033[1;32mH\033[0m - Hold, \033[1;35mR\033[0m - Release, \033[1;31mI\033[0m - Invalid" ); CLIDict_Def( matrixCLIDict, "Matrix Module Commands" ) = { CLIDict_Item( matrixDebug ), + CLIDict_Item( matrixInfo ), CLIDict_Item( matrixState ), { 0, 0, 0 } // Null entry for dictionary end }; @@ -110,7 +114,9 @@ uint8_t Matrix_pin( GPIO_Pin gpio, Type type ) // Assumes 0x40 between GPIO Port registers and 0x1000 between PORT pin registers // See Lib/mk20dx.h volatile unsigned int *GPIO_PDDR = (unsigned int*)(&GPIOA_PDDR) + gpio_offset; + #ifndef GHOSTING_MATRIX volatile unsigned int *GPIO_PSOR = (unsigned int*)(&GPIOA_PSOR) + gpio_offset; + #endif volatile unsigned int *GPIO_PCOR = (unsigned int*)(&GPIOA_PCOR) + gpio_offset; volatile unsigned int *GPIO_PDIR = (unsigned int*)(&GPIOA_PDIR) + gpio_offset; volatile unsigned int *PORT_PCR = (unsigned int*)(&PORTA_PCR0) + port_offset; @@ -119,13 +125,19 @@ uint8_t Matrix_pin( GPIO_Pin gpio, Type type ) switch ( type ) { case Type_StrobeOn: - *GPIO_PSOR |= (1 << gpio.pin); #ifdef GHOSTING_MATRIX - *GPIO_PDDR |= (1 << gpio.pin); // output + *GPIO_PCOR |= (1 << gpio.pin); + *GPIO_PDDR |= (1 << gpio.pin); // output, low + #else + *GPIO_PSOR |= (1 << gpio.pin); #endif break; case Type_StrobeOff: + #ifdef GHOSTING_MATRIX + // Ghosting martix needs to put not used (off) strobes in high impedance state + *GPIO_PDDR &= ~(1 << gpio.pin); // input, high Z state + #endif *GPIO_PCOR |= (1 << gpio.pin); #ifdef GHOSTING_MATRIX // Ghosting martix needs to put not used (off) strobes in high impedance state @@ -134,8 +146,13 @@ uint8_t Matrix_pin( GPIO_Pin gpio, Type type ) break; case Type_StrobeSetup: + #ifdef GHOSTING_MATRIX + *GPIO_PDDR &= ~(1 << gpio.pin); // input, high Z state + *GPIO_PCOR |= (1 << gpio.pin); + #else // Set as output pin *GPIO_PDDR |= (1 << gpio.pin); + #endif // Configure pin with slow slew, high drive strength and GPIO mux *PORT_PCR = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); @@ -154,7 +171,11 @@ uint8_t Matrix_pin( GPIO_Pin gpio, Type type ) break; case Type_Sense: + #ifdef GHOSTING_MATRIX // inverted + return *GPIO_PDIR & (1 << gpio.pin) ? 0 : 1; + #else return *GPIO_PDIR & (1 << gpio.pin) ? 1 : 0; + #endif case Type_SenseSetup: // Set as input pin @@ -190,30 +211,18 @@ void Matrix_setup() // Register Matrix CLI dictionary CLI_registerDictionary( matrixCLIDict, matrixCLIDictName ); - info_msg("Columns: "); - printHex( Matrix_colsNum ); - // Setup Strobe Pins for ( uint8_t pin = 0; pin < Matrix_colsNum; pin++ ) { Matrix_pin( Matrix_cols[ pin ], Type_StrobeSetup ); } - print( NL ); - info_msg("Rows: "); - printHex( Matrix_rowsNum ); - // Setup Sense Pins for ( uint8_t pin = 0; pin < Matrix_rowsNum; pin++ ) { Matrix_pin( Matrix_rows[ pin ], Type_SenseSetup ); } - print( NL ); - info_msg("Max Keys: "); - printHex( Matrix_maxKeys ); - print( NL ); - // Clear out Debounce Array for ( uint8_t item = 0; item < Matrix_maxKeys; item++ ) { @@ -294,9 +303,19 @@ void Matrix_scan( uint16_t scanNum ) // For each strobe, scan each of the sense pins for ( uint8_t strobe = 0; strobe < Matrix_colsNum; strobe++ ) { + #ifdef STROBE_DELAY + uint32_t start = micros(); + while ((micros() - start) < STROBE_DELAY); + #endif + // Strobe Pin Matrix_pin( Matrix_cols[ strobe ], Type_StrobeOn ); + #ifdef STROBE_DELAY + start = micros(); + while ((micros() - start) < STROBE_DELAY); + #endif + // Scan each of the sense pins for ( uint8_t sense = 0; sense < Matrix_rowsNum; sense++ ) { @@ -578,7 +597,22 @@ void Matrix_currentChange( unsigned int current ) // ----- CLI Command Functions ----- -void cliFunc_matrixDebug ( char* args ) +void cliFunc_matrixInfo( char* args ) +{ + print( NL ); + info_msg("Columns: "); + printHex( Matrix_colsNum ); + + print( NL ); + info_msg("Rows: "); + printHex( Matrix_rowsNum ); + + print( NL ); + info_msg("Max Keys: "); + printHex( Matrix_maxKeys ); +} + +void cliFunc_matrixDebug( char* args ) { // Parse number from argument // NOTE: Only first argument is used @@ -612,7 +646,7 @@ void cliFunc_matrixDebug ( char* args ) printInt8( matrixDebugMode ); } -void cliFunc_matrixState ( char* args ) +void cliFunc_matrixState( char* args ) { // Parse number from argument // NOTE: Only first argument is used diff --git a/Scan/WhiteFox/defaultMap.kll b/Scan/WhiteFox/defaultMap.kll index 6a4e641..037319b 100644 --- a/Scan/WhiteFox/defaultMap.kll +++ b/Scan/WhiteFox/defaultMap.kll @@ -95,7 +95,7 @@ ISSILedMask1 = " 0xFF, 0x00, /* C6-1 -> C6-16 */ 0xFF, 0x00, /* C7-1 -> C7-16 */ 0xFF, 0x00, /* C8-1 -> C8-16 */ - 0xFE, 0x00, /* C9-1 -> C9-16 */ + 0xFF, 0x00, /* C9-1 -> C9-16 */ "; # LED Brightness Override @@ -124,6 +124,6 @@ ISSILedBrightness1 = " 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C6-1 -> C6-16 */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C7-1 -> C7-16 */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C8-1 -> C8-16 */ -0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C9-1 -> C9-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C9-1 -> C9-16 */ ";