USB Joystick library, modified to work as a 6 DOF joystick.

Dependents:   USBJoystick_Test

Fork of USBJoystick by Wim Huiskamp

USBJoystick.cpp

Committer:
smartsystemdesign
Date:
2017-01-13
Revision:
2:1549541d3b4b
Parent:
1:8b5f213b169f
Child:
4:0ffbedd2cb73

File content as of revision 2:1549541d3b4b:

/* mbed USBJoystick Library
 * Copyright (c) 2012, v01:  Initial version, WH,
 *                           Modified USBMouse code ARM Limited.
 *                           (c) 2010-2011 mbed.org, MIT License
 *               2016, v02:  Updated USBDevice Lib, Added waitForConnect, Updated 32 bits button 
 *
 * 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, inclumosig 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, INCLUmosiG 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.
 */


#include "stdint.h"
#include "USBJoystick.h"

bool USBJoystick::update(int16_t x, int16_t y, int16_t z, int16_t rx, int16_t ry, int16_t rz, uint32_t buttons, uint8_t hat) {

   _x = x;
   _y = y;   
   _z = z;
   _rx = rx;
   _ry = ry;
   _rz = rz;
   _buttons = buttons;     
   _hat = hat;

   return update();
}
 
bool USBJoystick::update() {
   HID_REPORT report;

   // Fill the report according to the Joystick Descriptor
   report.data[0] = _x & 0xffff;            
   report.data[1] = _y & 0xffff;               
   report.data[2] = _z & 0xffff;            
   report.data[3] = _rx & 0xffff;
   report.data[4] = _ry & 0xffff;            
   report.data[5] = _rz & 0xffff;

#if (BUTTONS4 == 1)               
//Hat and 4 Buttons
//   report.data[4] = ((_buttons & 0x0f) << 4) | (_hat & 0x0f) ;                                      
//   report.length = 5; 


//Use 4 bit padding for hat4 or hat8
   report.data[6] = (_hat & 0x0f) ;                                      

//Use 4 bit padding for buttons   
   report.data[7] = (_buttons & 0x0f) ;                                         
   report.length = 8;
#endif

#if (BUTTONS8 == 1)               
//Hat and first 4 Buttons
//   report.data[4] = ((_buttons & 0x0f) << 4) | (_hat & 0x0f) ;                                      
//
//Use bit padding for last 4 Buttons
//   report.data[5] =  (_buttons & 0xf0) >> 4;                                         
//   report.length = 6; 

//Use 4 bit padding for hat4 or hat8
   report.data[6] = (_hat & 0x0f) ;                                      

//Use 8 bits for buttons   
   report.data[7] = (_buttons & 0xff) ;
   report.length = 8;
#endif

#if (BUTTONS32 == 1)               
//Use 4 bit padding for hat4 or hat8
   report.data[6] = (_hat & 0x0f) ;

//No bit padding for 32 buttons                                         
   report.data[7] = (_buttons >>  0) & 0xff;
   report.data[8] = (_buttons >>  8) & 0xff;
   report.data[9] = (_buttons >> 16) & 0xff;
   report.data[10] = (_buttons >> 24) & 0xff;
   report.length = 11;
#endif
       
   return send(&report);
}

bool USBJoystick::move(int16_t x, int16_t y, int16_t z, int16_t rx, int16_t ry, int16_t rz) {
   _x = x;
   _y = y;
   _z = z;
   _rx = rx;
   _ry = ry;
   _rz = rz;
   return update();
}

bool USBJoystick::buttons(uint32_t buttons) {
   _buttons = buttons;
   return update();
}

bool USBJoystick::hat(uint8_t hat) {
   _hat = hat;
   return update();
}

void USBJoystick::_init() {
   _x = 0x0000;
   _y = 0x0000;
   _z = 0x0000;
   _rx = 0x0000;
   _ry = 0x0000;
   _rz = 0x0000;
   _buttons = 0x00000000;
   _hat = 0x00;              
}


uint8_t * USBJoystick::reportDesc() {    
         static uint8_t reportDescriptor[] = {
            // value in () is the number of bytes.  These bytes follow the comma, least significant byte first
            // see USBHID_Types.h for more info
             USAGE_PAGE(1), 0x01,           // Generic Desktop           
             LOGICAL_MINIMUM(1), 0x00,      // Logical_Minimum (0)             
             USAGE(1), 0x04,                // Usage (Joystick)
             COLLECTION(1), 0x01,           // Application
             
// 6 Axes of Joystick
               USAGE_PAGE(1), 0x01,            // Generic Desktop
               USAGE(1), 0x01,                 // Usage (Pointer)
               COLLECTION(1), 0x00,            // Physical
                 USAGE(1), 0x30,                 // X
                 USAGE(1), 0x31,                 // Y
                 USAGE(1), 0x32,                 // Z
                 USAGE(1), 0x33,                 // RX
                 USAGE(1), 0x34,                 // RY
                 USAGE(1), 0x35,                 // RZ
                 LOGICAL_MINIMUM(2), 0xff, 0xff, // -32768 (using 2's complement)
                 LOGICAL_MAXIMUM(2), 0xff, 0x7f, // 32767 (0x7fff, least significant byte first)
                 REPORT_SIZE(1), 0x10,  // REPORT_SIZE describes the number of bits in this element (16, in this case)
                 REPORT_COUNT(1), 0x06,
                 INPUT(1), 0x02,                 // Data, Variable, Absolute                
               END_COLLECTION(0),               

#if (HAT4 == 1)
// 4 Position Hat Switch
               USAGE(1), 0x39,                 // Usage (Hat switch)
               LOGICAL_MINIMUM(1), 0x00,       // 0
               LOGICAL_MAXIMUM(1), 0x03,       // 3
               PHYSICAL_MINIMUM(1), 0x00,      // Physical_Minimum (0)
               PHYSICAL_MAXIMUM(2), 0x0E, 0x01, // Physical_Maximum (270)
               UNIT(1), 0x14,                  // Unit (Eng Rot:Angular Pos)                            
               REPORT_SIZE(1), 0x04,
               REPORT_COUNT(1), 0x01,
               INPUT(1), 0x02,                 // Data, Variable, Absolute               
#endif
#if (HAT8 == 1)
// 8 Position Hat Switch
               USAGE(1), 0x39,                 // Usage (Hat switch)
               LOGICAL_MINIMUM(1), 0x00,       // 0
               LOGICAL_MAXIMUM(1), 0x07,       // 7
               PHYSICAL_MINIMUM(1), 0x00,      // Physical_Minimum (0)
               PHYSICAL_MAXIMUM(2), 0x3B, 0x01, // Physical_Maximum (315)
               UNIT(1), 0x14,                  // Unit (Eng Rot:Angular Pos)                            
               REPORT_SIZE(1), 0x04,
               REPORT_COUNT(1), 0x01,
               INPUT(1), 0x02,                 // Data, Variable, Absolute               
#endif

// Padding 4 bits
               REPORT_SIZE(1), 0x01,
               REPORT_COUNT(1), 0x04,
               INPUT(1), 0x01,                 // Constant


#if (BUTTONS4 == 1)
// 4 Buttons
               USAGE_PAGE(1), 0x09,            // Buttons
               USAGE_MINIMUM(1), 0x01,         // 1
               USAGE_MAXIMUM(1), 0x04,         // 4
               LOGICAL_MINIMUM(1), 0x00,       // 0
               LOGICAL_MAXIMUM(1), 0x01,       // 1
               REPORT_SIZE(1), 0x01,
               REPORT_COUNT(1), 0x04,
               UNIT_EXPONENT(1), 0x00,         // Unit_Exponent (0)
               UNIT(1), 0x00,                  // Unit (None)                                           
               INPUT(1), 0x02,                 // Data, Variable, Absolute

// Padding 4 bits
               REPORT_SIZE(1), 0x01,
               REPORT_COUNT(1), 0x04,
               INPUT(1), 0x01,                 // Constant

#endif
#if (BUTTONS8 == 1)
// 8 Buttons
               USAGE_PAGE(1), 0x09,            // Buttons
               USAGE_MINIMUM(1), 0x01,         // 1
               USAGE_MAXIMUM(1), 0x08,         // 8
               LOGICAL_MINIMUM(1), 0x00,       // 0
               LOGICAL_MAXIMUM(1), 0x01,       // 1
               REPORT_SIZE(1), 0x01,
               REPORT_COUNT(1), 0x08,
               UNIT_EXPONENT(1), 0x00,         // Unit_Exponent (0)
               UNIT(1), 0x00,                  // Unit (None)                                           
               INPUT(1), 0x02,                 // Data, Variable, Absolute
#endif

#if (BUTTONS32 == 1)
// 32 Buttons
               USAGE_PAGE(1), 0x09,            // Buttons
               USAGE_MINIMUM(1), 0x01,         // 1
               USAGE_MAXIMUM(1), 0x20,         // 32
               LOGICAL_MINIMUM(1), 0x00,       // 0
               LOGICAL_MAXIMUM(1), 0x01,       // 1
               REPORT_SIZE(1), 0x01,
               REPORT_COUNT(1), 0x20,
               UNIT_EXPONENT(1), 0x00,         // Unit_Exponent (0)
               UNIT(1), 0x00,                  // Unit (None)                                           
               INPUT(1), 0x02,                 // Data, Variable, Absolute
#endif

             END_COLLECTION(0)
      };

      reportLength = sizeof(reportDescriptor);
      return reportDescriptor;
}