G27_Pedals_and_Shifter/lib/G27PedalsShifter.cpp

162 lines
4.0 KiB
C++

/*
G27PedalsShifter.cpp
Copyright (c) 2016, Jason Duncan
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
// (stolen from Matthew Heironimus @ https://github.com/MHeironimus/ArduinoJoystickLibrary)
#include "G27PedalsShifter.h"
#if defined(_USING_HID)
#define G27_REPORT_ID 0x03
#define G27_STATE_SIZE 9
static const uint8_t _hidReportDescriptor[] PROGMEM = {
// Joystick
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x04, // USAGE (Joystick)
0xa1, 0x01, // COLLECTION (Application)
0x85, G27_REPORT_ID, // REPORT_ID (3)
// 24 Buttons
0x05, 0x09, // USAGE_PAGE (Button)
0x19, 0x01, // USAGE_MINIMUM (Button 1)
0x29, 0x18, // USAGE_MAXIMUM (Button 24)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x75, 0x01, // REPORT_SIZE (1)
0x95, 0x18, // REPORT_COUNT (24)
0x55, 0x00, // UNIT_EXPONENT (0)
0x65, 0x00, // UNIT (None)
0x81, 0x02, // INPUT (Data,Var,Abs)
// X, Y, and Z Axis
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x26, 0xff, 0x03, // LOGICAL_MAXIMUM (1023)
0x75, 0x10, // REPORT_SIZE (16)
0x09, 0x01, // USAGE (Pointer)
0xA1, 0x00, // COLLECTION (Physical)
0x09, 0x30, // USAGE (x)
0x09, 0x31, // USAGE (y)
0x09, 0x32, // USAGE (z)
0x95, 0x03, // REPORT_COUNT (3)
0x81, 0x02, // INPUT (Data,Var,Abs)
0xc0, // END_COLLECTION
0xc0 // END_COLLECTION
};
G27_::G27_()
{
// Setup HID report structure
static HIDSubDescriptor node(_hidReportDescriptor, sizeof(_hidReportDescriptor));
HID().AppendDescriptor(&node);
// Initalize State
xAxis = 0;
yAxis = 0;
zAxis = 0;
buttons = 0;
}
void G27_::begin(bool initAutoSendState)
{
autoSendState = initAutoSendState;
sendState();
}
void G27_::end()
{
}
void G27_::setButton(uint8_t button, uint8_t value)
{
if (value == 0)
{
releaseButton(button);
}
else
{
pressButton(button);
}
}
void G27_::pressButton(uint8_t button)
{
bitSet(buttons, button);
if (autoSendState) sendState();
}
void G27_::releaseButton(uint8_t button)
{
bitClear(buttons, button);
if (autoSendState) sendState();
}
void G27_::setXAxis(uint16_t value)
{
xAxis = value;
if (autoSendState) sendState();
}
void G27_::setYAxis(uint16_t value)
{
yAxis = value;
if (autoSendState) sendState();
}
void G27_::setZAxis(uint16_t value)
{
zAxis = value;
if (autoSendState) sendState();
}
void G27_::sendState()
{
uint8_t data[G27_STATE_SIZE];
uint32_t tmp = buttons;
// Split 24 bit button-state into 3 bytes
data[0] = tmp & 0xFF;
tmp >>= 8;
data[1] = tmp & 0xFF;
tmp >>= 8;
data[2] = tmp & 0xFF;
// axis get 2 bytes each
tmp = xAxis;
data[3] = tmp & 0xFF;
tmp >>=8;
data[4] = tmp & 0xFF;
tmp = yAxis;
data[5] = tmp & 0xFF;
tmp >>=8;
data[6] = tmp & 0xFF;
tmp = zAxis;
data[7] = tmp & 0xFF;
tmp >>=8;
data[8] = tmp & 0xFF;
// HID().SendReport(Report number, array of values in same order as HID descriptor, length)
HID().SendReport(G27_REPORT_ID, data, G27_STATE_SIZE);
}
G27_ G27;
#endif