Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implement joystick-USB-api from diff #2702

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
146 changes: 146 additions & 0 deletions hardware/arduino/avr/cores/arduino/HID.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,27 @@
** SOFTWARE.
*/

#include "Platform.h"
#include "USBAPI.h"
#include "USBDesc.h"

#if defined(USBCON)
#ifdef HID_ENABLED

// *** This used to be RAWHID_ENABLED
//#define RAWHID_ENABLED
//#define KBAM_ENABLED
#define JOYHID_ENABLED

// Singletons for mouse and keyboard

Mouse_ Mouse;
Keyboard_ Keyboard;

// *** Add a joystick too

Joystick_ Joystick;

//================================================================================
//================================================================================

Expand Down Expand Up @@ -123,6 +132,91 @@ const u8 _hidReportDescriptor[] = {
0x09, 0x02, // usage
0x91, 0x02, // Output (array)
0xC0 // end collection
#endif
// *** Here is where the RAW_HID has been converted to a Joystick device
// *** Inspired by helmpcb.com/electronics/usb-joystick
// *** Check out www.usb.org/developers/hidpage/ for more than you'll ever need to know about USB HID
// *** HID descriptor created using the HID descriptor tool from www.usb.org/developers/hidpage/dt2_4.zip (win32)

#ifdef JOYHID_ENABLED

// 32 buttons (and a throttle - just in case the game doesn't recognise a joystick with no analog axis)

0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x04, // USAGE (Joystick)
0xa1, 0x01, // COLLECTION (Application)
0x85, 0x03, // REPORT_ID (3) (This is important when HID_SendReport() is called)

//Buttons:
0x05, 0x09, // USAGE_PAGE (Button)
0x19, 0x01, // USAGE_MINIMUM (Button 1)
0x29, 0x20, // USAGE_MAXIMUM (Button 32)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x75, 0x01, // REPORT_SIZE (1)
0x95, 0x20, // REPORT_COUNT (32)
0x55, 0x00, // UNIT_EXPONENT (0)
0x65, 0x00, // UNIT (None)
0x81, 0x02, // INPUT (Data,Var,Abs)

// 8 bit Throttle and Steering
0x05, 0x02, // USAGE_PAGE (Simulation Controls)

0x15, 0x00, // LOGICAL_MINIMUM (0)
0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255)
0xA1, 0x00, // COLLECTION (Physical)
0x09, 0xBB, // USAGE (Throttle)
0x09, 0xBA, // USAGE (Steering)
0x75, 0x08, // REPORT_SIZE (8)
0x95, 0x02, // REPORT_COUNT (2)
0x81, 0x02, // INPUT (Data,Var,Abs)

0xc0, // END_COLLECTION
// Two Hat switches

0x05, 0x01, // USAGE_PAGE (Generic Desktop)

0x09, 0x39, // USAGE (Hat switch)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x07, // LOGICAL_MAXIMUM (7)
0x35, 0x00, // PHYSICAL_MINIMUM (0)
0x46, 0x3B, 0x01, // PHYSICAL_MAXIMUM (315)
0x65, 0x14, // UNIT (Eng Rot:Angular Pos)
0x75, 0x04, // REPORT_SIZE (4)
0x95, 0x01, // REPORT_COUNT (1)
0x81, 0x02, // INPUT (Data,Var,Abs)

0x09, 0x39, // USAGE (Hat switch)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x07, // LOGICAL_MAXIMUM (7)
0x35, 0x00, // PHYSICAL_MINIMUM (0)
0x46, 0x3B, 0x01, // PHYSICAL_MAXIMUM (315)
0x65, 0x14, // UNIT (Eng Rot:Angular Pos)
0x75, 0x04, // REPORT_SIZE (4)
0x95, 0x01, // REPORT_COUNT (1)
0x81, 0x02, // INPUT (Data,Var,Abs)

0x15, 0x00, // LOGICAL_MINIMUM (0)
0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255)
0x75, 0x08, // REPORT_SIZE (8)

0x09, 0x01, // USAGE (Pointer)
0xA1, 0x00, // COLLECTION (Physical)
0x09, 0x30, // USAGE (x)
0x09, 0x31, // USAGE (y)
0x09, 0x32, // USAGE (z)
0x09, 0x33, // USAGE (rx)
0x09, 0x34, // USAGE (ry)
0x09, 0x35, // USAGE (rz)
0x95, 0x06, // REPORT_COUNT (2)
0x81, 0x02, // INPUT (Data,Var,Abs)
0xc0, // END_COLLECTION

0xc0 // END_COLLECTION




#endif
};

Expand All @@ -143,6 +237,7 @@ u8 _hid_idle = 1;

#define WEAK __attribute__ ((weak))


int WEAK HID_GetInterface(u8* interfaceNum)
{
interfaceNum[0] += 1; // uses 1
Expand Down Expand Up @@ -195,12 +290,63 @@ bool WEAK HID_Setup(Setup& setup)
return false;
}

//================================================================================
//================================================================================
// Joystick
// Usage: Joystick.move(inputs go here)
//
// The report data format must match the one defined in the descriptor exactly
// or it either won't work, or the pc will make a mess of unpacking the data
//

Joystick_::Joystick_()
{
}


#define joyBytes 13 // should be equivalent to sizeof(JoyState_t)

void Joystick_::setState(JoyState_t *joySt)
{
uint8_t data[joyBytes];
uint32_t buttonTmp;
buttonTmp = joySt->buttons;

data[0] = buttonTmp & 0xFF; // Break 32 bit button-state out into 4 bytes, to send over USB
buttonTmp >>= 8;
data[1] = buttonTmp & 0xFF;
buttonTmp >>= 8;
data[2] = buttonTmp & 0xFF;
buttonTmp >>= 8;
data[3] = buttonTmp & 0xFF;

data[4] = joySt->throttle; // Throttle
data[5] = joySt->rudder; // Steering

data[6] = (joySt->hatSw2 << 4) | joySt->hatSw1; // Pack hat-switch states into a single byte

data[7] = joySt->xAxis; // X axis
data[8] = joySt->yAxis; // Y axis
data[9] = joySt->zAxis; // Z axis
data[10] = joySt->xRotAxis; // rX axis
data[11] = joySt->yRotAxis; // rY axis
data[12] = joySt->zRotAxis; // rZ axis

//HID_SendReport(Report number, array of values in same order as HID descriptor, length)
HID_SendReport(3, data, joyBytes);
// The joystick is specified as using report 3 in the descriptor. That's where the "3" comes from
}




//================================================================================
//================================================================================
// Mouse

Mouse_::Mouse_(void) : _buttons(0)
{

}

void Mouse_::begin(void)
Expand Down
42 changes: 40 additions & 2 deletions hardware/arduino/avr/cores/arduino/USBAPI.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,16 @@ class Serial_ : public Stream
{
private:
int peek_buffer;
ring_buffer *_cdc_rx_buffer;
public:
Serial_() { peek_buffer = -1; };
void begin(unsigned long);
void begin(unsigned long, uint8_t);
void begin(uint16_t baud_count);
void end(void);

virtual int available(void);
virtual void accept(void);
virtual int peek(void);
virtual int read(void);
virtual void flush(void);
Expand All @@ -90,7 +93,42 @@ class Serial_ : public Stream
};
extern Serial_ Serial;

#define HAVE_CDCSERIAL
//================================================================================
//================================================================================
// Joystick
// Implemented in HID.cpp
// The list of parameters here needs to match the implementation in HID.cpp


typedef struct JoyState // Pretty self explanitory. Simple state to store all the joystick parameters
{
uint8_t xAxis;
uint8_t yAxis;
uint8_t zAxis;

uint8_t xRotAxis;
uint8_t yRotAxis;
uint8_t zRotAxis;

uint8_t throttle;
uint8_t rudder;

uint8_t hatSw1;
uint8_t hatSw2;

uint32_t buttons; // 32 general buttons

} JoyState_t;

class Joystick_
{
public:
Joystick_();

void setState(JoyState_t *joySt);

};
extern Joystick_ Joystick;

//================================================================================
//================================================================================
Expand All @@ -111,7 +149,7 @@ class Mouse_
void begin(void);
void end(void);
void click(uint8_t b = MOUSE_LEFT);
void move(signed char x, signed char y, signed char wheel = 0);
void move(signed char x, signed char y, signed char wheel = 0);
void press(uint8_t b = MOUSE_LEFT); // press LEFT by default
void release(uint8_t b = MOUSE_LEFT); // release LEFT by default
bool isPressed(uint8_t b = MOUSE_LEFT); // check LEFT by default
Expand Down
Loading