Skip to content

Add support for Arduino Zero #262

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

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
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
4 changes: 2 additions & 2 deletions library.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ name=Joystick
version=2.1.1
author=Matthew Heironimus
maintainer=Matthew Heironimus <[email protected]>
sentence=Allows an Arduino board with USB capabilities (e.g. Leonardo, Arduino Micro, Arudino Due, etc.) to appear as a Joystick or Gamepad.
sentence=Allows an Arduino board with USB capabilities (e.g. Leonardo, Arduino Micro, Arudino Due, R4 minima etc.) to appear as a Joystick or Gamepad.
paragraph=This library is built on the PluggableUSB library. It can be used with or without other HID-based libraries (Mouse, Keyboard, etc.).
category=Device Control
url=https://github.com/MHeironimus/ArduinoJoystickLibrary
architectures=avr,sam
architectures=avr,sam,samd,renesas
20 changes: 19 additions & 1 deletion src/DynamicHID/DynamicHID.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@

#include "DynamicHID.h"

#if !defined(ARDUINO_SAMD_VARIANT_COMPLIANCE)

#if defined(USBCON)

#ifdef _VARIANT_ARDUINO_DUE_X_
Expand Down Expand Up @@ -70,14 +72,23 @@ int DynamicHID_::getDescriptor(USBSetup& setup)
return total;
}

void DynamicHID_::setShortName(char* name) {
strlcpy(serialname, name, ISERIAL_MAX_LEN);
}

uint8_t DynamicHID_::getShortName(char *name)
{
// Up to 20 char (null char included)
// Example from Arduino:
/*
name[0] = 'H';
name[1] = 'I';
name[2] = 'D';
name[3] = 'A' + (descriptorSize & 0x0F);
name[4] = 'A' + ((descriptorSize >> 4) & 0x0F);
return 5;
*/
int len = strlcpy(name, serialname, ISERIAL_MAX_LEN);
return len;
}

void DynamicHID_::AppendDescriptor(DynamicHIDSubDescriptor *node)
Expand Down Expand Up @@ -163,7 +174,14 @@ DynamicHID_::DynamicHID_(void) : PluggableUSBModule(1, 1, epType),

int DynamicHID_::begin(void)
{
serialname[0] = 'H';
serialname[1] = 'I';
serialname[2] = 'D';
serialname[3] = 'A' + (descriptorSize & 0x0F);
serialname[4] = 'A' + ((descriptorSize >> 4) & 0x0F);
return 0;
}

#endif /* if defined(USBCON) */

#endif // !defined(!defined(ARDUINO_SAMD_VARIANT_COMPLIANCE))
16 changes: 10 additions & 6 deletions src/DynamicHID/DynamicHID.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,19 @@
#include <stdint.h>
#include <Arduino.h>


#if !defined(ARDUINO_SAMD_VARIANT_COMPLIANCE) && !defined(ARDUINO_ARCH_RENESAS)

#ifdef _VARIANT_ARDUINO_DUE_X_
// The following values are the same as AVR's USBAPI.h
// Reproduced here because SAM doesn't have these in
// its own USBAPI.H
#define USB_EP_SIZE 64
#define TRANSFER_PGM 0x80

#define EPTYPE_DESCRIPTOR_SIZE uint32_t
#include "USB/PluggableUSB.h"
#else
#define EPTYPE_DESCRIPTOR_SIZE uint8_t
#include "PluggableUSB.h"
#endif

Expand Down Expand Up @@ -110,6 +114,7 @@ class DynamicHID_ : public PluggableUSBModule
int begin(void);
int SendReport(uint8_t id, const void* data, int len);
void AppendDescriptor(DynamicHIDSubDescriptor* node);
void setShortName(char* name);

protected:
// Implementation of the PluggableUSBModule
Expand All @@ -119,17 +124,14 @@ class DynamicHID_ : public PluggableUSBModule
uint8_t getShortName(char* name);

private:
#ifdef _VARIANT_ARDUINO_DUE_X_
uint32_t epType[1];
#else
uint8_t epType[1];
#endif
EPTYPE_DESCRIPTOR_SIZE epType[1];

DynamicHIDSubDescriptor* rootNode;
uint16_t descriptorSize;

uint8_t protocol;
uint8_t idle;
char serialname[ISERIAL_MAX_LEN];
};

// Replacement for global singleton.
Expand All @@ -142,3 +144,5 @@ DynamicHID_& DynamicHID();
#endif // USBCON

#endif // DYNAMIC_HID_h

#endif // !defined(ARDUINO_SAMD_VARIANT_COMPLIANCE) && !defined(ARDUINO_ARCH_RENESAS)
38 changes: 25 additions & 13 deletions src/Joystick.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,26 +20,26 @@

#include "Joystick.h"

#if defined(_USING_DYNAMIC_HID)
#if defined(_USING_DYNAMIC_HID) || defined(_USING_HID)

#define JOYSTICK_REPORT_ID_INDEX 7
#define JOYSTICK_AXIS_MINIMUM 0
#define JOYSTICK_AXIS_MAXIMUM 65535
#define JOYSTICK_SIMULATOR_MINIMUM 0
#define JOYSTICK_SIMULATOR_MAXIMUM 65535

#define JOYSTICK_INCLUDE_X_AXIS B00000001
#define JOYSTICK_INCLUDE_Y_AXIS B00000010
#define JOYSTICK_INCLUDE_Z_AXIS B00000100
#define JOYSTICK_INCLUDE_RX_AXIS B00001000
#define JOYSTICK_INCLUDE_RY_AXIS B00010000
#define JOYSTICK_INCLUDE_RZ_AXIS B00100000
#define JOYSTICK_INCLUDE_X_AXIS 0b00000001
#define JOYSTICK_INCLUDE_Y_AXIS 0b00000010
#define JOYSTICK_INCLUDE_Z_AXIS 0b00000100
#define JOYSTICK_INCLUDE_RX_AXIS 0b00001000
#define JOYSTICK_INCLUDE_RY_AXIS 0b00010000
#define JOYSTICK_INCLUDE_RZ_AXIS 0b00100000

#define JOYSTICK_INCLUDE_RUDDER B00000001
#define JOYSTICK_INCLUDE_THROTTLE B00000010
#define JOYSTICK_INCLUDE_ACCELERATOR B00000100
#define JOYSTICK_INCLUDE_BRAKE B00001000
#define JOYSTICK_INCLUDE_STEERING B00010000
#define JOYSTICK_INCLUDE_RUDDER 0b00000001
#define JOYSTICK_INCLUDE_THROTTLE 0b00000010
#define JOYSTICK_INCLUDE_ACCELERATOR 0b00000100
#define JOYSTICK_INCLUDE_BRAKE 0b00001000
#define JOYSTICK_INCLUDE_STEERING 0b00010000

Joystick_::Joystick_(
uint8_t hidReportId,
Expand Down Expand Up @@ -437,8 +437,16 @@ Joystick_::Joystick_(
memcpy(customHidReportDescriptor, tempHidReportDescriptor, hidReportDescriptorSize);

// Register HID Report Description
#if defined(_USING_DYNAMIC_HID)
DynamicHIDSubDescriptor *node = new DynamicHIDSubDescriptor(customHidReportDescriptor, hidReportDescriptorSize, false);
DynamicHID().AppendDescriptor(node);
char name[] = "JOYSTICK_0";
name[strlen(name)-1] = '0' + (hidReportId-2);
DynamicHID().setShortName(name);
#else
HIDSubDescriptor *node = new HIDSubDescriptor(customHidReportDescriptor, hidReportDescriptorSize);
HID().AppendDescriptor(node);
#endif

// Setup Joystick State
if (buttonCount > 0) {
Expand Down Expand Up @@ -657,7 +665,7 @@ void Joystick_::sendState()
}

// Pack hat-switch states into a single byte
data[index++] = (convertedHatSwitch[1] << 4) | (B00001111 & convertedHatSwitch[0]);
data[index++] = (convertedHatSwitch[1] << 4) | (0b00001111 & convertedHatSwitch[0]);

} // Hat Switches

Expand All @@ -676,7 +684,11 @@ void Joystick_::sendState()
index += buildAndSetSimulationValue(_includeSimulatorFlags & JOYSTICK_INCLUDE_BRAKE, _brake, _brakeMinimum, _brakeMaximum, &(data[index]));
index += buildAndSetSimulationValue(_includeSimulatorFlags & JOYSTICK_INCLUDE_STEERING, _steering, _steeringMinimum, _steeringMaximum, &(data[index]));

#if defined(_USING_DYNAMIC_HID)
DynamicHID().SendReport(_hidReportId, data, _hidReportSize);
#else
HID().SendReport(_hidReportId, data, _hidReportSize);
#endif
}

#endif
21 changes: 14 additions & 7 deletions src/Joystick.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,23 +21,29 @@
#ifndef JOYSTICK_h
#define JOYSTICK_h

#include "DynamicHID/DynamicHID.h"
#include <Arduino.h>

#if defined(ARDUINO_SAMD_VARIANT_COMPLIANCE) || defined(ARDUINO_ARCH_RENESAS)
#include <HID.h>
#else
#include <DynamicHID/DynamicHID.h>
#endif // defined(ARDUINO_SAMD_VARIANT_COMPLIANCE) || defined(ARDUINO_ARCH_RENESAS)

#if ARDUINO < 10606
#error The Joystick library requires Arduino IDE 1.6.6 or greater. Please update your IDE.
#endif // ARDUINO < 10606

#if ARDUINO > 10606
#if !defined(USBCON)
#error The Joystick library can only be used with a USB MCU (e.g. Arduino Leonardo, Arduino Micro, etc.).
#endif // !defined(USBCON)
#if !defined(USBCON) && !defined(_USING_HID)
#error The Joystick library can only be used with a USB MCU (e.g. Arduino Leonardo, Arduino Micro, etc.).
#endif // !defined(USBCON)
#endif // ARDUINO > 10606

#if !defined(_USING_DYNAMIC_HID)
#if !defined(_USING_DYNAMIC_HID) && !defined(_USING_HID)

#warning "Using legacy HID core (non pluggable)"

#else // !defined(_USING_DYNAMIC_HID)
#else // !defined(_USING_DYNAMIC_HID) && !defined(_USING_HID)

//================================================================================
// Joystick (Gamepad)
Expand Down Expand Up @@ -214,5 +220,6 @@ class Joystick_
void sendState();
};

#endif // !defined(_USING_DYNAMIC_HID)
#endif // !defined(_USING_DYNAMIC_HID) && !defined(_USING_HID)

#endif // JOYSTICK_h