changeset 429:970dab727f47

Adding basic mouse button support - Full Mouse support will have to wait for KLL 0.6 * This will include dynamic HID descriptor generation for many wheels and axis depending on the KLL needs - HID descriptor is currently limited to 8 buttons - Technically mouse movement also works (tested by accident), but it's disable for now (needs some API thought) - Adding additional udev rules - Added KRO mode default define
author Jacob Alexander <haata@kiibohd.com>
date Mon, 21 Mar 2016 00:43:19 -0700
parents b5746c43904e
children d3cef419c849
files 98-kiibohd.rules Output/pjrcUSB/arm/usb_desc.c Output/pjrcUSB/arm/usb_mouse.c Output/pjrcUSB/arm/usb_mouse.h Output/pjrcUSB/capabilities.kll Output/pjrcUSB/output_com.c Output/pjrcUSB/output_com.h
diffstat 7 files changed, 154 insertions(+), 51 deletions(-) [+]
line wrap: on
line diff
--- a/98-kiibohd.rules	Fri Mar 04 00:23:48 2016 -0800
+++ b/98-kiibohd.rules	Mon Mar 21 00:43:19 2016 -0700
@@ -2,20 +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]?", 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"
 
--- a/Output/pjrcUSB/arm/usb_desc.c	Fri Mar 04 00:23:48 2016 -0800
+++ b/Output/pjrcUSB/arm/usb_desc.c	Mon Mar 21 00:43:19 2016 -0700
@@ -314,22 +314,17 @@
 	0xa1, 0x02,        //   Collection (Logical)
 	0x09, 0x01,        //     Usage (Pointer)
 
-	// Buttons (5 bits)
+	// Buttons (8 bits)
 	0xa1, 0x00,        //     Collection (Physical) - Buttons
 	0x05, 0x09,        //       Usage Page (Button)
 	0x19, 0x01,        //       Usage Minimum (Button 1)
-	0x29, 0x05,        //       Usage Maximum (Button 5)
+	0x29, 0x08,        //       Usage Maximum (Button 8)
 	0x15, 0x00,        //       Logical Minimum (0)
 	0x25, 0x01,        //       Logical Maximum (1)
 	0x75, 0x01,        //       Report Size (1)
-	0x95, 0x05,        //       Report Count (5)
+	0x95, 0x08,        //       Report Count (8)
 	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)
 	0x05, 0x01,        //       Usage PAGE (Generic Desktop)
 	0x09, 0x30,        //       Usage (X)
--- a/Output/pjrcUSB/arm/usb_mouse.c	Fri Mar 04 00:23:48 2016 -0800
+++ b/Output/pjrcUSB/arm/usb_mouse.c	Mon Mar 21 00:43:19 2016 -0700
@@ -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 -----
 
+static uint8_t transmit_previous_timeout = 0;
+
 // which buttons are currently pressed
-uint8_t usb_mouse_buttons_state=0;
+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;
+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;
+
+	// 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 (left) mask |= 1;
-        if (middle) mask |= 4;
-        if (right) mask |= 2;
-        usb_mouse_buttons_state = mask;
-        return usb_mouse_move(0, 0, 0);
+		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 Document each byte
+        // TODO Dynamically generate this code based on KLL requirements
+        *(tx_packet->buf + 0) = USBMouse_Buttons;
+        *(tx_packet->buf + 1) = 0;
+        *(tx_packet->buf + 2) = 0;
+        *(tx_packet->buf + 3) = 0;
+        *(tx_packet->buf + 4) = 0;
+        tx_packet->len = 5;
+        usb_tx( MOUSE_ENDPOINT, tx_packet );
+
+        // Clear status and state
+        USBMouse_Buttons = 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)
 {
--- a/Output/pjrcUSB/arm/usb_mouse.h	Fri Mar 04 00:23:48 2016 -0800
+++ b/Output/pjrcUSB/arm/usb_mouse.h	Mon Mar 21 00:43:19 2016 -0700
@@ -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)
-
--- a/Output/pjrcUSB/capabilities.kll	Fri Mar 04 00:23:48 2016 -0800
+++ b/Output/pjrcUSB/capabilities.kll	Mon Mar 21 00:43:19 2016 -0700
@@ -1,10 +1,10 @@
 Name = pjrcUSBCapabilities;
-Version = 0.6;
-Author = "HaaTa (Jacob Alexander) 2014-2015";
-KLL = 0.3c;
+Version = 0.7;
+Author = "HaaTa (Jacob Alexander) 2014-2016";
+KLL = 0.3d;
 
 # Modified Date
-Date = 2015-08-21;
+Date = 2016-03-20;
 
 
 # Output capabilities
@@ -12,6 +12,7 @@
 noneOut     => Output_noneSend_capability();
 sysCtrlOut  => Output_sysCtrlSend_capability( sysCode : 1 );
 usbKeyOut   => Output_usbCodeSend_capability( usbCode : 1 );
+mouseOut    => Output_usbMouse_capability( mouseCode : 2 );
 
 # Configuration capabilities
 kbdProtocolBoot => Output_kbdProtocolBoot_capability();
@@ -21,6 +22,12 @@
 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
--- a/Output/pjrcUSB/output_com.c	Fri Mar 04 00:23:48 2016 -0800
+++ b/Output/pjrcUSB/output_com.c	Mon Mar 21 00:43:19 2016 -0700
@@ -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 <kll_defs.h>
+
 // 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,21 @@
 // 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;
+
 // 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
+uint8_t 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 +516,48 @@
 	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 #
+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)");
+		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]);
+
+	// If set to zero, ignore
+	if ( mouse_button == 0 )
+		return;
+
+	// Adjust for bit shift
+	mouse_button -= 1;
+
+	// Only send mouse button if in press or hold state
+	if ( stateType == 0x00 && state == 0x03 ) // Release state
+	{
+		USBMouse_Buttons &= ~(1 << mouse_button);
+	}
+	else
+	{
+		USBMouse_Buttons |= (1 << mouse_button);
+	}
+
+	// TODO Add more states when adding full support
+	USBMouse_Changed = 1;
+}
+
 
 
 // ----- Functions -----
@@ -552,6 +605,10 @@
 		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();
--- a/Output/pjrcUSB/output_com.h	Fri Mar 04 00:23:48 2016 -0800
+++ b/Output/pjrcUSB/output_com.h	Mon Mar 21 00:43:19 2016 -0700
@@ -72,11 +72,14 @@
 
 extern volatile uint8_t  USBKeys_Protocol; // 0 - Boot Mode, 1 - NKRO Mode
 
+extern volatile uint16_t USBMouse_Buttons; // Bitmask for mouse buttons
+
 // 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          uint8_t  USBMouse_Changed;
 
 extern volatile uint8_t  Output_Available; // 0 - Output module not fully functional, 1 - Output module working