A usb interface emulating an Xbox 360 controller

Dependencies:   USBDevice

Support for rumble is not done yet.

Please note this is work in progress.

tested so far with LPC1769 and LPC11u35

Xinput.h

Committer:
olyeah
Date:
2016-09-16
Revision:
0:430276835afe

File content as of revision 0:430276835afe:

/*
 * Xinput.h
 *
 *  Created on: 8 sept. 2016
 *      Author: Olivier Chabloz
 */

#ifndef XINPUT_H_
#define XINPUT_H_

#include "USBDevice.h"
#include "USBHID.h"

#define DEVICE_CLASS    0xFF
#define DEVICE_SUBCLASS 0xFF
#define DEVICE_PROTOCOL 0xFF
#define DEVICE_VERSION 0x0114
#define DEVICE_ATTRIBUTES 0xA0
#define DEVICE_POWER    0xFA
#define VENDOR_ID       0x045e
#define PRODUCT_ID      0x028e
#define MANUFACTURER_NAME   {'©','M','i','c','r','o','s','o','f','t'}
#define MANUFACTURER_NAME_LEN   10
#define PRODUCT_NAME        {'C','o','n','t','r','o','l','l','e','r'}
#define PRODUCT_NAME_LEN    10
#define EP0_SIZE    8
#define NUM_ENDPOINTS   6
#define NUM_USB_BUFFERS 24
#define NUM_INTERFACE   4
#define XINPUT_INTERFACE    0
#define XINPUT_RX_ENDPOINT  EP2OUT
#define XINPUT_RX_SIZE 3
#define XINPUT_TX_ENDPOINT  EP1IN
#define XINPUT_TX_SIZE 20
#define CONFIG_DESC_SIZE 153
#define ENDPOINT1_CONFIG ENDPOINT_TRANSIMIT_ONLY
#define ENDPOINT2_CONFIG ENDPOINT_RECEIVE_ONLY
#define ENDPOINT3_CONFIG ENDPOINT_TRANSIMIT_ONLY
#define ENDPOINT4_CONFIG ENDPOINT_RECEIVE_ONLY
#define ENDPOINT5_CONFIG ENDPOINT_TRANSMIT_AND_RECEIVE
#define ENDPOINT6_CONFIG ENDPOINT_TRANSIMIT_ONLY



#define BUTTON_Y    15
#define BUTTON_X    14
#define BUTTON_B    13
#define BUTTON_A    12

#define BUTTON_LOGO 10
#define BUTTON_RB    9
#define BUTTON_LB    8
#define BUTTON_R3    7
#define BUTTON_L3    6
#define BUTTON_Back  5
#define BUTTON_Start 4
#define BUTTON_Right 3
#define BUTTON_Left  2
#define BUTTON_Down  1
#define BUTTON_Up    0


#define STICK_LEFT_X  1
#define STICK_LEFT_Y  2
#define STICK_RIGHT_X 3
#define STICK_RIGHT_Y 4
#define TRIGGER_LEFT  5
#define TRIGGER_RIGHT 6



class Xinput: public USBDevice {
public:
    Xinput():
        USBDevice( VENDOR_ID, PRODUCT_ID, 0x0001), buttons(0), left_stick_x(0), left_stick_y(0), right_stick_x(0), right_stick_y(0), left_trigger(0), right_trigger(0){
        connect();
    };

    virtual ~Xinput();


    /*
    * Get device descriptor. Warning: this method has to store the length of the report descriptor in reportLength.
    *
    * @returns pointer to the device descriptor
    */
    virtual uint8_t * deviceDesc();

    /*
    * Get string manufacturer descriptor
    *
    * @returns pointer to the string manufacturer descriptor
    */
    virtual uint8_t * stringImanufacturerDesc();

    /*
    * Get string product descriptor
    *
    * @returns pointer to the string product descriptor
    */
    virtual uint8_t * stringIproductDesc();

    /*
    * Get string configuration descriptor
    *
    * @returns pointer to the string configuration descriptor
    */
    virtual uint8_t * stringIConfigurationDesc();

    /*
    * Called by USBDevice layer. Set configuration of the device.
    * For instance, you can add all endpoints that you need on this function.
    *
    * @param configuration Number of the configuration
    * @returns true if class handles this request
    */
    virtual bool USBCallback_setConfiguration(uint8_t configuration);



    bool read_leds(uint8_t * data);
    void send_controls(void);
    void clear(void);

    /*
    * Update Xinput buttons
    *
    * @param button The button number to update
    * @param status 1 to activate, 0 to desactivate
    */
    void update_button(uint8_t button, uint8_t status);

    void update_analog(uint8_t stick, int16_t value);
    void update_analog(uint8_t stick, uint8_t value);
protected:
    /*
    * Get configuration descriptor
    *
    * @returns pointer to the configuration descriptor
    */
    virtual uint8_t * configurationDesc();

private:
    uint16_t buttons;
    int16_t left_stick_x;
    int16_t left_stick_y;
    int16_t right_stick_x;
    int16_t right_stick_y;
    uint8_t left_trigger;
    uint8_t right_trigger;
};

#endif /* XINPUT_H_ */