add support for hid gamepad interface
add documentation for HID joystick Add joystick_task to read analog axes values even when no key is pressed or release. update doc Update docs/feature_joystick.md Manage pin setup and read to maintain matrix scan after analog read
This commit is contained in:
		
							parent
							
								
									d8f3c28a37
								
							
						
					
					
						commit
						3cf7611139
					
				
					 15 changed files with 675 additions and 2 deletions
				
			
		| 
						 | 
				
			
			@ -71,6 +71,9 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		|||
#ifdef MIDI_ENABLE
 | 
			
		||||
#    include "process_midi.h"
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef JOYSTICK_ENABLE
 | 
			
		||||
#   include "process_joystick.h"
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef HD44780_ENABLE
 | 
			
		||||
#    include "hd44780.h"
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -396,6 +399,10 @@ MATRIX_LOOP_END:
 | 
			
		|||
    }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef JOYSTICK_ENABLE
 | 
			
		||||
    joystick_task();
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    // update LED
 | 
			
		||||
    if (led_status != host_keyboard_leds()) {
 | 
			
		||||
        led_status = host_keyboard_leds();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -47,6 +47,10 @@
 | 
			
		|||
extern keymap_config_t keymap_config;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef JOYSTICK_ENABLE
 | 
			
		||||
# include <quantum/joystick.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* ---------------------------------------------------------
 | 
			
		||||
 *       Global interface variables and declarations
 | 
			
		||||
 * ---------------------------------------------------------
 | 
			
		||||
| 
						 | 
				
			
			@ -246,6 +250,9 @@ typedef struct {
 | 
			
		|||
#endif
 | 
			
		||||
#ifdef VIRTSER_ENABLE
 | 
			
		||||
            usb_driver_config_t serial_driver;
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef JOYSTICK_ENABLE
 | 
			
		||||
            usb_driver_config_t joystick_driver;
 | 
			
		||||
#endif
 | 
			
		||||
        };
 | 
			
		||||
        usb_driver_config_t array[0];
 | 
			
		||||
| 
						 | 
				
			
			@ -283,6 +290,14 @@ static usb_driver_configs_t drivers = {
 | 
			
		|||
#    define CDC_OUT_MODE USB_EP_MODE_TYPE_BULK
 | 
			
		||||
    .serial_driver = QMK_USB_DRIVER_CONFIG(CDC, CDC_NOTIFICATION_EPNUM, false),
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef JOYSTICK_ENABLE
 | 
			
		||||
  #define JOYSTICK_IN_CAPACITY 4
 | 
			
		||||
  #define JOYSTICK_OUT_CAPACITY 4
 | 
			
		||||
  #define JOYSTICK_IN_MODE USB_EP_MODE_TYPE_BULK
 | 
			
		||||
  #define JOYSTICK_OUT_MODE USB_EP_MODE_TYPE_BULK
 | 
			
		||||
  .joystick_driver = QMK_USB_DRIVER_CONFIG(JOYSTICK, 0, false),
 | 
			
		||||
#endif
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define NUM_USB_DRIVERS (sizeof(drivers) / sizeof(usb_driver_config_t))
 | 
			
		||||
| 
						 | 
				
			
			@ -870,3 +885,61 @@ void virtser_task(void) {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef JOYSTICK_ENABLE
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    #if JOYSTICK_AXES_COUNT>0
 | 
			
		||||
    int8_t  axes[JOYSTICK_AXES_COUNT];
 | 
			
		||||
    #endif
 | 
			
		||||
    
 | 
			
		||||
    #if JOYSTICK_BUTTON_COUNT>0
 | 
			
		||||
    uint8_t buttons[(JOYSTICK_BUTTON_COUNT-1)/8+1];
 | 
			
		||||
    #endif
 | 
			
		||||
} __attribute__ ((packed)) joystick_report_t;
 | 
			
		||||
 | 
			
		||||
void send_joystick_packet(joystick_t* joystick) {
 | 
			
		||||
    joystick_report_t rep = {
 | 
			
		||||
      #if JOYSTICK_AXES_COUNT>0
 | 
			
		||||
      .axes = {
 | 
			
		||||
          joystick->axes[0]
 | 
			
		||||
 | 
			
		||||
        #if JOYSTICK_AXES_COUNT >= 2
 | 
			
		||||
          ,joystick->axes[1]
 | 
			
		||||
        #endif
 | 
			
		||||
        #if JOYSTICK_AXES_COUNT >= 3
 | 
			
		||||
          ,joystick->axes[2]
 | 
			
		||||
        #endif
 | 
			
		||||
        #if JOYSTICK_AXES_COUNT >= 4
 | 
			
		||||
          ,joystick->axes[3]
 | 
			
		||||
        #endif
 | 
			
		||||
        #if JOYSTICK_AXES_COUNT >= 5
 | 
			
		||||
          ,joystick->axes[4]
 | 
			
		||||
        #endif
 | 
			
		||||
        #if JOYSTICK_AXES_COUNT >= 6
 | 
			
		||||
          ,joystick->axes[5]
 | 
			
		||||
        #endif
 | 
			
		||||
      },
 | 
			
		||||
      #endif //JOYSTICK_AXES_COUNT>0
 | 
			
		||||
      
 | 
			
		||||
      #if JOYSTICK_BUTTON_COUNT>0
 | 
			
		||||
      .buttons = {
 | 
			
		||||
          joystick->buttons[0]
 | 
			
		||||
          
 | 
			
		||||
        #if JOYSTICK_BUTTON_COUNT>8
 | 
			
		||||
          ,joystick->buttons[1]
 | 
			
		||||
        #endif
 | 
			
		||||
        #if JOYSTICK_BUTTON_COUNT>16
 | 
			
		||||
          ,joystick->buttons[2]
 | 
			
		||||
        #endif
 | 
			
		||||
        #if JOYSTICK_BUTTON_COUNT>24
 | 
			
		||||
          ,joystick->buttons[3]
 | 
			
		||||
        #endif
 | 
			
		||||
      }
 | 
			
		||||
      #endif //JOYSTICK_BUTTON_COUNT>0
 | 
			
		||||
  };
 | 
			
		||||
  
 | 
			
		||||
  chnWrite(&drivers.joystick_driver.driver, (uint8_t*)&rep, sizeof(rep));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -85,6 +85,10 @@ extern keymap_config_t keymap_config;
 | 
			
		|||
#    include "raw_hid.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef JOYSTICK_ENABLE
 | 
			
		||||
	#include "joystick.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
uint8_t keyboard_idle = 0;
 | 
			
		||||
/* 0: Boot Protocol, 1: Report Protocol(default) */
 | 
			
		||||
uint8_t        keyboard_protocol  = 1;
 | 
			
		||||
| 
						 | 
				
			
			@ -263,6 +267,85 @@ static void Console_Task(void) {
 | 
			
		|||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*******************************************************************************
 | 
			
		||||
 * Joystick
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
#ifdef JOYSTICK_ENABLE
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    #if JOYSTICK_AXES_COUNT>0
 | 
			
		||||
    int8_t  axes[JOYSTICK_AXES_COUNT];
 | 
			
		||||
    #endif
 | 
			
		||||
    
 | 
			
		||||
    #if JOYSTICK_BUTTON_COUNT>0
 | 
			
		||||
    uint8_t buttons[(JOYSTICK_BUTTON_COUNT-1)/8+1];
 | 
			
		||||
    #endif
 | 
			
		||||
} __attribute__ ((packed)) joystick_report_t;
 | 
			
		||||
 | 
			
		||||
void send_joystick_packet(joystick_t* joystick){
 | 
			
		||||
    
 | 
			
		||||
    uint8_t timeout = 255;
 | 
			
		||||
    uint8_t where = where_to_send();
 | 
			
		||||
    
 | 
			
		||||
    if (where != OUTPUT_USB && where != OUTPUT_USB_AND_BT) {
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    joystick_report_t r = {
 | 
			
		||||
        #if JOYSTICK_AXES_COUNT>0
 | 
			
		||||
        .axes = {
 | 
			
		||||
            joystick->axes[0]
 | 
			
		||||
 | 
			
		||||
          #if JOYSTICK_AXES_COUNT >= 2
 | 
			
		||||
            ,joystick->axes[1]
 | 
			
		||||
          #endif
 | 
			
		||||
          #if JOYSTICK_AXES_COUNT >= 3
 | 
			
		||||
            ,joystick->axes[2]
 | 
			
		||||
          #endif
 | 
			
		||||
          #if JOYSTICK_AXES_COUNT >= 4
 | 
			
		||||
            ,joystick->axes[3]
 | 
			
		||||
          #endif
 | 
			
		||||
          #if JOYSTICK_AXES_COUNT >= 5
 | 
			
		||||
            ,joystick->axes[4]
 | 
			
		||||
          #endif
 | 
			
		||||
          #if JOYSTICK_AXES_COUNT >= 6
 | 
			
		||||
            ,joystick->axes[5]
 | 
			
		||||
          #endif
 | 
			
		||||
        },
 | 
			
		||||
        #endif //JOYSTICK_AXES_COUNT>0
 | 
			
		||||
        
 | 
			
		||||
        #if JOYSTICK_BUTTON_COUNT>0
 | 
			
		||||
        .buttons = {
 | 
			
		||||
            joystick->buttons[0]
 | 
			
		||||
            
 | 
			
		||||
          #if JOYSTICK_BUTTON_COUNT>8
 | 
			
		||||
            ,joystick->buttons[1]
 | 
			
		||||
          #endif
 | 
			
		||||
          #if JOYSTICK_BUTTON_COUNT>16
 | 
			
		||||
            ,joystick->buttons[2]
 | 
			
		||||
          #endif
 | 
			
		||||
          #if JOYSTICK_BUTTON_COUNT>24
 | 
			
		||||
            ,joystick->buttons[3]
 | 
			
		||||
          #endif
 | 
			
		||||
        }
 | 
			
		||||
        #endif //JOYSTICK_BUTTON_COUNT>0
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /* Select the Joystick Report Endpoint */
 | 
			
		||||
    Endpoint_SelectEndpoint(JOYSTICK_IN_EPNUM);
 | 
			
		||||
 | 
			
		||||
    /* Check if write ready for a polling interval around 10ms */
 | 
			
		||||
    while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
 | 
			
		||||
    if (!Endpoint_IsReadWriteAllowed()) return;
 | 
			
		||||
 | 
			
		||||
    /* Write Joystick Report Data */
 | 
			
		||||
    Endpoint_Write_Stream_LE(&r, sizeof(joystick_report_t), NULL);
 | 
			
		||||
 | 
			
		||||
    /* Finalize the stream transfer to send the last packet */
 | 
			
		||||
    Endpoint_ClearIN();
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*******************************************************************************
 | 
			
		||||
 * USB Events
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -278,6 +278,53 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM ConsoleReport[] = {
 | 
			
		|||
};
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef JOYSTICK_ENABLE
 | 
			
		||||
const USB_Descriptor_HIDReport_Datatype_t PROGMEM JoystickReport[] =
 | 
			
		||||
{
 | 
			
		||||
    HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
 | 
			
		||||
    HID_RI_USAGE(8, 0x04), /* Joystick */
 | 
			
		||||
    HID_RI_COLLECTION(8, 0x01), /* Application */
 | 
			
		||||
        HID_RI_USAGE(8, 0x01), /* Pointer */
 | 
			
		||||
        HID_RI_COLLECTION(8, 0x00), /* Physical */
 | 
			
		||||
 | 
			
		||||
            #if JOYSTICK_AXES_COUNT >= 1 
 | 
			
		||||
                HID_RI_USAGE(8, 0x30),     //     USAGE (X)
 | 
			
		||||
            #endif
 | 
			
		||||
            #if JOYSTICK_AXES_COUNT >= 2 
 | 
			
		||||
                HID_RI_USAGE(8, 0x31),     //     USAGE (Y)
 | 
			
		||||
            #endif
 | 
			
		||||
            #if JOYSTICK_AXES_COUNT >= 3 
 | 
			
		||||
                HID_RI_USAGE(8, 0x32),     //     USAGE (Z)
 | 
			
		||||
            #endif
 | 
			
		||||
            #if JOYSTICK_AXES_COUNT >= 4 
 | 
			
		||||
                HID_RI_USAGE(8, 0x33),     //     USAGE (RX)
 | 
			
		||||
            #endif
 | 
			
		||||
            #if JOYSTICK_AXES_COUNT >= 5 
 | 
			
		||||
                HID_RI_USAGE(8, 0x34),     //     USAGE (RY)
 | 
			
		||||
            #endif
 | 
			
		||||
            #if JOYSTICK_AXES_COUNT >= 6 
 | 
			
		||||
                HID_RI_USAGE(8, 0x35),     //     USAGE (RZ)
 | 
			
		||||
            #endif
 | 
			
		||||
            HID_RI_LOGICAL_MINIMUM(8, -127),
 | 
			
		||||
            HID_RI_LOGICAL_MAXIMUM(8, 127),
 | 
			
		||||
            HID_RI_REPORT_COUNT(8, JOYSTICK_AXES_COUNT),
 | 
			
		||||
            HID_RI_REPORT_SIZE(8, 0x08),
 | 
			
		||||
            HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE),
 | 
			
		||||
            
 | 
			
		||||
            HID_RI_USAGE_PAGE(8, 0x09), /* Button */
 | 
			
		||||
            HID_RI_USAGE_MINIMUM(8, 0x01),  /* Button 1 */
 | 
			
		||||
            HID_RI_USAGE_MAXIMUM(8, JOYSTICK_BUTTON_COUNT),  /* Button 5 */
 | 
			
		||||
            HID_RI_LOGICAL_MINIMUM(8, 0x00),
 | 
			
		||||
            HID_RI_LOGICAL_MAXIMUM(8, 0x01),
 | 
			
		||||
            HID_RI_REPORT_COUNT(8, JOYSTICK_BUTTON_COUNT),
 | 
			
		||||
            HID_RI_REPORT_SIZE(8, 0x01),
 | 
			
		||||
            HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
 | 
			
		||||
            
 | 
			
		||||
        HID_RI_END_COLLECTION(0),
 | 
			
		||||
    HID_RI_END_COLLECTION(0),
 | 
			
		||||
};
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Device descriptor
 | 
			
		||||
 */
 | 
			
		||||
| 
						 | 
				
			
			@ -287,7 +334,6 @@ const USB_Descriptor_Device_t PROGMEM DeviceDescriptor = {
 | 
			
		|||
        .Type                   = DTYPE_Device
 | 
			
		||||
    },
 | 
			
		||||
    .USBSpecification           = VERSION_BCD(1, 1, 0),
 | 
			
		||||
 | 
			
		||||
#if VIRTSER_ENABLE
 | 
			
		||||
    .Class                      = USB_CSCP_IADDeviceClass,
 | 
			
		||||
    .SubClass                   = USB_CSCP_IADDeviceSubclass,
 | 
			
		||||
| 
						 | 
				
			
			@ -812,6 +858,49 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor = {
 | 
			
		|||
        .PollingIntervalMS      = 0x05
 | 
			
		||||
    },
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * Joystick
 | 
			
		||||
     */
 | 
			
		||||
#ifdef JOYSTICK_ENABLE
 | 
			
		||||
    .Joystick_Interface =
 | 
			
		||||
        {
 | 
			
		||||
            .Header                 = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
 | 
			
		||||
 | 
			
		||||
            .InterfaceNumber        = JOYSTICK_INTERFACE,
 | 
			
		||||
            .AlternateSetting       = 0x00,
 | 
			
		||||
 | 
			
		||||
            .TotalEndpoints         = 1,
 | 
			
		||||
 | 
			
		||||
            .Class                  = HID_CSCP_HIDClass,
 | 
			
		||||
            .SubClass               = HID_CSCP_NonBootSubclass,
 | 
			
		||||
            .Protocol               = HID_CSCP_NonBootProtocol,
 | 
			
		||||
 | 
			
		||||
            .InterfaceStrIndex      = NO_DESCRIPTOR
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
    .Joystick_HID =
 | 
			
		||||
        {
 | 
			
		||||
            .Header                 = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
 | 
			
		||||
 | 
			
		||||
            .HIDSpec                = VERSION_BCD(1,1,1),
 | 
			
		||||
            .CountryCode            = 0x00,
 | 
			
		||||
            .TotalReportDescriptors = 1,
 | 
			
		||||
            .HIDReportType          = HID_DTYPE_Report,
 | 
			
		||||
            .HIDReportLength        = sizeof(JoystickReport)
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
    .Joystick_INEndpoint =
 | 
			
		||||
        {
 | 
			
		||||
            .Header                 = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
 | 
			
		||||
 | 
			
		||||
            .EndpointAddress        = (ENDPOINT_DIR_IN | JOYSTICK_IN_EPNUM),
 | 
			
		||||
            .Attributes             = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
 | 
			
		||||
            .EndpointSize           = JOYSTICK_EPSIZE,
 | 
			
		||||
            .PollingIntervalMS      = 0x0A
 | 
			
		||||
        },
 | 
			
		||||
#endif
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
| 
						 | 
				
			
			@ -943,6 +1032,12 @@ uint16_t get_usb_descriptor(const uint16_t wValue, const uint16_t wIndex, const
 | 
			
		|||
                    Size    = sizeof(USB_HID_Descriptor_HID_t);
 | 
			
		||||
 | 
			
		||||
                    break;
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef JOYSTICK_ENABLE
 | 
			
		||||
            case JOYSTICK_INTERFACE:
 | 
			
		||||
                Address = &ConfigurationDescriptor.Joystick_HID;
 | 
			
		||||
                Size    = sizeof(USB_HID_Descriptor_HID_t);
 | 
			
		||||
                break;
 | 
			
		||||
#endif
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -987,6 +1082,12 @@ uint16_t get_usb_descriptor(const uint16_t wValue, const uint16_t wIndex, const
 | 
			
		|||
                    Size    = sizeof(ConsoleReport);
 | 
			
		||||
 | 
			
		||||
                    break;
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef JOYSTICK_ENABLE
 | 
			
		||||
            case JOYSTICK_INTERFACE:
 | 
			
		||||
                Address = &JoystickReport;
 | 
			
		||||
                Size    = sizeof(JoystickReport);
 | 
			
		||||
                break;
 | 
			
		||||
#endif
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -123,6 +123,13 @@ typedef struct {
 | 
			
		|||
    USB_Descriptor_Endpoint_t  CDC_DataOutEndpoint;
 | 
			
		||||
    USB_Descriptor_Endpoint_t  CDC_DataInEndpoint;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef JOYSTICK_ENABLE
 | 
			
		||||
    // Joystick HID Interface
 | 
			
		||||
    USB_Descriptor_Interface_t            Joystick_Interface;
 | 
			
		||||
    USB_HID_Descriptor_HID_t              Joystick_HID;
 | 
			
		||||
    USB_Descriptor_Endpoint_t             Joystick_INEndpoint;
 | 
			
		||||
#endif
 | 
			
		||||
} USB_Descriptor_Configuration_t;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
| 
						 | 
				
			
			@ -164,6 +171,9 @@ enum usb_interfaces {
 | 
			
		|||
    CDI_INTERFACE,
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(JOYSTICK_ENABLE)
 | 
			
		||||
    JOYSTICK_INTERFACE,
 | 
			
		||||
#endif
 | 
			
		||||
    TOTAL_INTERFACES
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -224,6 +234,10 @@ enum usb_endpoints {
 | 
			
		|||
#    define CDC_IN_EPADDR (ENDPOINT_DIR_IN | CDC_IN_EPNUM)
 | 
			
		||||
#    define CDC_OUT_EPADDR (ENDPOINT_DIR_OUT | CDC_OUT_EPNUM)
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef JOYSTICK_ENABLE
 | 
			
		||||
    JOYSTICK_IN_EPNUM = NEXT_EPNUM,
 | 
			
		||||
    JOYSTICK_OUT_EPNUM = NEXT_EPNUM,
 | 
			
		||||
#endif
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#ifdef PROTOCOL_LUFA
 | 
			
		||||
| 
						 | 
				
			
			@ -248,6 +262,7 @@ enum usb_endpoints {
 | 
			
		|||
#define MIDI_STREAM_EPSIZE 64
 | 
			
		||||
#define CDC_NOTIFICATION_EPSIZE 8
 | 
			
		||||
#define CDC_EPSIZE 16
 | 
			
		||||
#define JOYSTICK_EPSIZE 8
 | 
			
		||||
 | 
			
		||||
uint16_t get_usb_descriptor(const uint16_t wValue, const uint16_t wIndex, const void** const DescriptorAddress);
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,6 +26,8 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		|||
#include "debug.h"
 | 
			
		||||
#include "host_driver.h"
 | 
			
		||||
#include "vusb.h"
 | 
			
		||||
#include "joystick.h"
 | 
			
		||||
#include "joystick.h"
 | 
			
		||||
#include <util/delay.h>
 | 
			
		||||
 | 
			
		||||
static uint8_t vusb_keyboard_leds = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -79,6 +81,7 @@ static void    send_keyboard(report_keyboard_t *report);
 | 
			
		|||
static void    send_mouse(report_mouse_t *report);
 | 
			
		||||
static void    send_system(uint16_t data);
 | 
			
		||||
static void    send_consumer(uint16_t data);
 | 
			
		||||
static void    send_joystick(void);
 | 
			
		||||
 | 
			
		||||
static host_driver_t driver = {keyboard_leds, send_keyboard, send_mouse, send_system, send_consumer};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -139,6 +142,68 @@ static void send_consumer(uint16_t data) {
 | 
			
		|||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    uint8_t report_id;
 | 
			
		||||
 | 
			
		||||
    #if JOYSTICK_AXES_COUNT>0
 | 
			
		||||
    int8_t  axes[JOYSTICK_AXES_COUNT];
 | 
			
		||||
    #endif
 | 
			
		||||
 | 
			
		||||
    #if JOYSTICK_BUTTON_COUNT>0
 | 
			
		||||
    uint8_t buttons[(JOYSTICK_BUTTON_COUNT-1)/8+1];
 | 
			
		||||
    #endif
 | 
			
		||||
} __attribute__ ((packed)) vusb_joystick_report_t;
 | 
			
		||||
 | 
			
		||||
void send_joystick_packet(joystick_t* status)
 | 
			
		||||
{
 | 
			
		||||
    vusb_joystick_report_t r = {
 | 
			
		||||
        .report_id = 0x4,
 | 
			
		||||
 | 
			
		||||
        #if JOYSTICK_AXES_COUNT>0
 | 
			
		||||
        .axes = {
 | 
			
		||||
            status->axes[0]
 | 
			
		||||
 | 
			
		||||
          #if JOYSTICK_AXES_COUNT >= 2
 | 
			
		||||
            ,status->axes[1]
 | 
			
		||||
          #endif
 | 
			
		||||
          #if JOYSTICK_AXES_COUNT >= 3
 | 
			
		||||
            ,status->axes[2]
 | 
			
		||||
          #endif
 | 
			
		||||
          #if JOYSTICK_AXES_COUNT >= 4
 | 
			
		||||
            ,status->axes[3]
 | 
			
		||||
          #endif
 | 
			
		||||
          #if JOYSTICK_AXES_COUNT >= 5
 | 
			
		||||
            ,status->axes[4]
 | 
			
		||||
          #endif
 | 
			
		||||
          #if JOYSTICK_AXES_COUNT >= 6
 | 
			
		||||
            ,status->axes[5]
 | 
			
		||||
          #endif
 | 
			
		||||
        },
 | 
			
		||||
        #endif //JOYSTICK_AXES_COUNT>0
 | 
			
		||||
 | 
			
		||||
        #if JOYSTICK_BUTTON_COUNT>0
 | 
			
		||||
        .buttons = {
 | 
			
		||||
            status->buttons[0]
 | 
			
		||||
 | 
			
		||||
          #if JOYSTICK_BUTTON_COUNT>8
 | 
			
		||||
            ,status->buttons[1]
 | 
			
		||||
          #endif
 | 
			
		||||
          #if JOYSTICK_BUTTON_COUNT>16
 | 
			
		||||
            ,status->buttons[2]
 | 
			
		||||
          #endif
 | 
			
		||||
          #if JOYSTICK_BUTTON_COUNT>24
 | 
			
		||||
            ,status->buttons[3]
 | 
			
		||||
          #endif
 | 
			
		||||
        }
 | 
			
		||||
        #endif //JOYSTICK_BUTTON_COUNT>0
 | 
			
		||||
    };
 | 
			
		||||
    if (usbInterruptIsReady3()) {
 | 
			
		||||
        usbSetInterrupt3((void *)&r, sizeof(vusb_joystick_report_t));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*------------------------------------------------------------------*
 | 
			
		||||
 * Request from host                                                *
 | 
			
		||||
 *------------------------------------------------------------------*/
 | 
			
		||||
| 
						 | 
				
			
			@ -251,7 +316,7 @@ const PROGMEM uchar keyboard_hid_report[] = {
 | 
			
		|||
    0xC0         // End Collection
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#if defined(MOUSE_ENABLE) || defined(EXTRAKEY_ENABLE)
 | 
			
		||||
#if defined(MOUSE_ENABLE) || defined(EXTRAKEY_ENABLE) || defined(JOYSTICK_ENABLE)
 | 
			
		||||
const PROGMEM uchar mouse_extra_hid_report[] = {
 | 
			
		||||
#    ifdef MOUSE_ENABLE
 | 
			
		||||
    // Mouse report descriptor
 | 
			
		||||
| 
						 | 
				
			
			@ -332,6 +397,47 @@ const PROGMEM uchar mouse_extra_hid_report[] = {
 | 
			
		|||
    0x81, 0x00,                //   Input (Data, Array, Absolute)
 | 
			
		||||
    0xC0                       // End Collection
 | 
			
		||||
#    endif
 | 
			
		||||
#if JOYSTICK_ENABLE
 | 
			
		||||
    0x05, 0x01,     // USAGE_PAGE (Generic Desktop)
 | 
			
		||||
    0x09, 0x04,     // USAGE (Joystick)
 | 
			
		||||
    0xa1, 0x01,     // COLLECTION (Application)
 | 
			
		||||
    0x85, 0x4,      //   REPORT_ID (4)
 | 
			
		||||
    0x09, 0x01,     //   USAGE (Pointer)
 | 
			
		||||
    0xa1, 0x00,     //   COLLECTION (Physical)
 | 
			
		||||
  #if JOYSTICK_AXES_COUNT >= 1
 | 
			
		||||
    0x09, 0x30,     //     USAGE (X)
 | 
			
		||||
  #endif
 | 
			
		||||
  #if JOYSTICK_AXES_COUNT >= 2
 | 
			
		||||
    0x09, 0x31,     //     USAGE (Y)
 | 
			
		||||
  #endif
 | 
			
		||||
  #if JOYSTICK_AXES_COUNT >= 3
 | 
			
		||||
    0x09, 0x32,     //     USAGE (Z)
 | 
			
		||||
  #endif
 | 
			
		||||
  #if JOYSTICK_AXES_COUNT >= 4
 | 
			
		||||
    0x09, 0x33,     //     USAGE (RX)
 | 
			
		||||
  #endif
 | 
			
		||||
  #if JOYSTICK_AXES_COUNT >= 5
 | 
			
		||||
    0x09, 0x34,     //     USAGE (RY)
 | 
			
		||||
  #endif
 | 
			
		||||
  #if JOYSTICK_AXES_COUNT >= 6
 | 
			
		||||
    0x09, 0x35,     //     USAGE (RZ)
 | 
			
		||||
  #endif
 | 
			
		||||
    0x15, 0x81,     //   LOGICAL_MINIMUM (-127)
 | 
			
		||||
    0x25, 0x7f,     //   LOGICAL_MAXIMUM (127)
 | 
			
		||||
    0x75, 0x08,     //   REPORT_SIZE (8)
 | 
			
		||||
    0x95, JOYSTICK_AXES_COUNT,     //   REPORT_COUNT (JOYSTICK_AXES_COUNT)
 | 
			
		||||
    0x81, 0x02,     //   INPUT (Data,Var,Abs)
 | 
			
		||||
    0xc0,           // END_COLLECTION
 | 
			
		||||
    0x05, 0x09,     // USAGE_PAGE (Button)
 | 
			
		||||
    0x19, 0x01,     //   USAGE_MINIMUM (Button 1)
 | 
			
		||||
    0x29, JOYSTICK_BUTTON_COUNT,     //   USAGE_MAXIMUM
 | 
			
		||||
    0x15, 0x00,     //   LOGICAL_MINIMUM (0)
 | 
			
		||||
    0x25, 0x01,     //   LOGICAL_MAXIMUM (1)
 | 
			
		||||
    0x75, 0x01,     // REPORT_SIZE (1)
 | 
			
		||||
    0x95, JOYSTICK_BUTTON_COUNT,     // REPORT_COUNT
 | 
			
		||||
    0x81, 0x02,     // INPUT (Data,Var,Abs)
 | 
			
		||||
    0xc0 // END_COLLECTION
 | 
			
		||||
#endif //GAMEPAD_ENABLE
 | 
			
		||||
};
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue