This is a work in progress. Trying to make a working arcade button to USB interface with the Nucleo F411RE.

Dependencies:   USBDevice mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers USBGamepad.cpp Source File

USBGamepad.cpp

00001 /* Copyright (c) 2010-2011 mbed.org, MIT License
00002 * Modified Mouse code for Joystick - WH 2012
00003 * Modified for RetroPie MW 2016
00004 *
00005 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
00006 * and associated documentation files (the "Software"), to deal in the Software without
00007 * restriction, including without limitation the rights to use, copy, modify, merge, publish,
00008 * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
00009 * Software is furnished to do so, subject to the following conditions:
00010 *
00011 * The above copyright notice and this permission notice shall be included in all copies or
00012 * substantial portions of the Software.
00013 *
00014 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
00015 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00016 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
00017 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00018 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00019 */
00020  
00021 #include "stdint.h"
00022 #include "USBGamepad.h"
00023 
00024 
00025 
00026 bool USBGamepad::update(uint32_t buttons) 
00027 {
00028    _buttonsP1 = (uint16_t)(buttons & 0xffff);
00029    _buttonsP2 = (uint16_t)((buttons >> 16) & 0xffff);
00030    return update();
00031 }
00032  
00033 bool USBGamepad::update() 
00034 {
00035    HID_REPORT report;
00036 
00037    // Fill the report according to the Gamepad Descriptor
00038 
00039     #define put(idx, val) (report.data[idx] = (val) & 0xff, report.data[(idx)+1] = ((val) >> 8) & 0xff)
00040        
00041     report.data[0] = 0x01;  //Report id 1
00042     put(1, _buttonsP1); // 0..1 2 bytes    
00043     
00044     send(&report);
00045 
00046     report.data[0] = 0x02;  //Report id 2
00047     put(1, _buttonsP1); 
00048     
00049     send(&report);
00050    
00051     put(2, _buttonsP2);//  2..3 2 bytes, 32 buttons
00052    
00053    // important: keep reportLen in sync with the actual byte length of
00054    // the reports we build here
00055    report.length = REPORT_LEN;
00056  
00057    // send the report
00058    return sendNB(&report);
00059 }
00060 
00061 bool USBGamepad::buttons(uint32_t buttons) 
00062 {
00063      _buttonsP1 = (uint16_t)(buttons & 0xffff);
00064      _buttonsP2 = (uint16_t)((buttons >> 16) & 0xffff);
00065      return update();
00066 }
00067 
00068  
00069 void USBGamepad::_init() {
00070  
00071    _buttonsP1 = 0x0000; // 16 buttons
00072    _buttonsP2 = 0x0000; // 16 buttons
00073    
00074 }
00075  
00076  
00077 uint8_t * USBGamepad::reportDesc() 
00078 {    
00079 
00080 static const uint8_t reportDescriptor[27] = {
00081     0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
00082     0x09, 0x05,                    // USAGE (Game Pad)
00083     0xa1, 0x01,                    // COLLECTION (Application)
00084     0xa1, 0x00,                    //   COLLECTION (Physical)
00085     0x85, 0x01,                    //     REPORT_ID (1)
00086     0x05, 0x09,                    //     USAGE_PAGE (Button)
00087     0x19, 0x01,                    //     USAGE_MINIMUM (Button 1)
00088     0x29, 0x10,                    //     USAGE_MAXIMUM (Button 16)
00089     0x15, 0x00,                    //     LOGICAL_MINIMUM (0)
00090     0x25, 0x01,                    //     LOGICAL_MAXIMUM (1)
00091     0x75, 0x01,                    //     REPORT_SIZE (1)
00092     0x95, 0x10,                    //     REPORT_COUNT (16)
00093     0x81, 0x02,                    //     INPUT (Data,Var,Abs)
00094     0xc0                           // END_COLLECTION
00095     0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
00096     0x09, 0x05,                    // USAGE (Game Pad)
00097     0xa1, 0x01,                    // COLLECTION (Application)
00098     0xa1, 0x00,                    //   COLLECTION (Physical)
00099     0x85, 0x02,                    //     REPORT_ID (2)
00100     0x05, 0x09,                    //     USAGE_PAGE (Button)
00101     0x19, 0x01,                    //     USAGE_MINIMUM (Button 1)
00102     0x29, 0x10,                    //     USAGE_MAXIMUM (Button 16)
00103     0x15, 0x00,                    //     LOGICAL_MINIMUM (0)
00104     0x25, 0x01,                    //     LOGICAL_MAXIMUM (1)
00105     0x75, 0x01,                    //     REPORT_SIZE (1)
00106     0x95, 0x10,                    //     REPORT_COUNT (16)
00107     0x81, 0x02,                    //     INPUT (Data,Var,Abs)
00108     0xc0                           // END_COLLECTION
00109 };
00110 
00111       reportLength = sizeof(reportDescriptor);
00112       return reportDescriptor;
00113 }
00114  
00115  uint8_t * USBGamepad::stringImanufacturerDesc() {
00116     static uint8_t stringImanufacturerDescriptor[] = {
00117         0x15,                                            /*bLength*/
00118         STRING_DESCRIPTOR,                               /*bDescriptorType 0x03*/
00119         't',0,'h',0,'e',0,'t',0,'a',0,'z',0,'z',0,'b',0,'o',0,'t',0        /*bString iManufacturer - mjrcorp*/
00120     };
00121     return stringImanufacturerDescriptor;
00122 }
00123 
00124 uint8_t * USBGamepad::stringIserialDesc() {
00125     static uint8_t stringIserialDescriptor[] = {
00126         0x16,                                                           /*bLength*/
00127         STRING_DESCRIPTOR,                                              /*bDescriptorType 0x03*/
00128         '0',0,'1',0,'2',0,'3',0,'4',0,'5',0,'6',0,'7',0,'8',0,'9',0,    /*bString iSerial - 0123456789*/
00129     };
00130     return stringIserialDescriptor;
00131 }
00132 
00133 uint8_t * USBGamepad::stringIproductDesc() {
00134     static uint8_t stringIproductDescriptor[] = {
00135         0x1E,                                                       /*bLength*/
00136         STRING_DESCRIPTOR,                                          /*bDescriptorType 0x03*/
00137         'A',0,'r',0,'c',0,'a',0,'d',0,'e',0,' ',0,'G',0,
00138         'a',0,'m',0,'e',0,'p',0,'a',0,'d',0                         /*String iProduct */
00139     };
00140     return stringIproductDescriptor;
00141 }