mirror of
https://github.com/mon/PocketVoltex.git
synced 2026-10-07 22:28:10 +03:00
Add joystick interface, fix STALL bugs maybe
This commit is contained in:
@@ -5,7 +5,12 @@
|
||||
|
||||
#define MAGIC_NUMBER 42
|
||||
|
||||
static sdvx_config_t defaults PROGMEM = {
|
||||
uint8_t firstRun EEMEM; // init to 255
|
||||
sdvx_config_t eeConfig EEMEM;
|
||||
|
||||
sdvx_config_t sdvxConfig;
|
||||
|
||||
static const PROGMEM sdvx_config_t defaults = {
|
||||
.switches = {
|
||||
HID_KEYBOARD_SC_Z,
|
||||
HID_KEYBOARD_SC_X,
|
||||
@@ -13,20 +18,27 @@ static sdvx_config_t defaults PROGMEM = {
|
||||
HID_KEYBOARD_SC_SLASH_AND_QUESTION_MARK,
|
||||
HID_KEYBOARD_SC_C,
|
||||
HID_KEYBOARD_SC_M,
|
||||
HID_KEYBOARD_SC_ENTER},
|
||||
//.ledsOn = true,
|
||||
HID_KEYBOARD_SC_ENTER,
|
||||
HID_KEYBOARD_SC_KEYPAD_PLUS}, // macro
|
||||
.btColour = {BRIGHTNESS_MAX, BRIGHTNESS_MAX, BRIGHTNESS_MAX}, // white
|
||||
.fxColour = {BRIGHTNESS_MAX, BRIGHTNESS_MAX/4, 0}, // orange
|
||||
.knobColours = {
|
||||
{0,BRIGHTNESS_MAX,BRIGHTNESS_MAX}, // aqua
|
||||
{BRIGHTNESS_MAX,0,BRIGHTNESS_MAX} // pink
|
||||
},
|
||||
.lightsOn = 1,
|
||||
.hidLights = 1,
|
||||
.keyLights = 1,
|
||||
.knobLights = 1,
|
||||
.lightPattern = FOLLOWER,
|
||||
.macroClick = HID_KEYBOARD_SC_KEYPAD_PLUS,
|
||||
.macroPin = {HID_KEYBOARD_SC_KEYPAD_0_AND_INSERT,
|
||||
HID_KEYBOARD_SC_KEYPAD_0_AND_INSERT,
|
||||
HID_KEYBOARD_SC_KEYPAD_0_AND_INSERT,
|
||||
HID_KEYBOARD_SC_KEYPAD_0_AND_INSERT}
|
||||
.joystickMode = 1,
|
||||
};
|
||||
|
||||
uint8_t firstRun EEMEM; // init to 255
|
||||
sdvx_config_t eeConfig EEMEM;
|
||||
|
||||
sdvx_config_t sdvxConfig;
|
||||
|
||||
void InitConfig(void) {
|
||||
if (eeprom_read_byte(&firstRun) != MAGIC_NUMBER) { // store defaults
|
||||
memcpy_P(&sdvxConfig, &defaults, sizeof(sdvx_config_t));
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
// 7 gameplay switches + macro combo switch
|
||||
#define SWITCH_COUNT 8
|
||||
#define JOYSTICK_PPR (24 * 4)
|
||||
#define MAGIC_RESET_NUMBER 42
|
||||
// divide by 10 for actual version
|
||||
#define FIRMWARE_VERSION 1
|
||||
@@ -21,15 +22,17 @@ typedef struct {
|
||||
RGB_t btColour;
|
||||
RGB_t fxColour;
|
||||
RGB_t knobColours[2];
|
||||
bool lightsOn;
|
||||
bool hidLights;
|
||||
bool keyLights;
|
||||
bool knobLights;
|
||||
uint8_t lightsOn;
|
||||
uint8_t hidLights;
|
||||
uint8_t keyLights;
|
||||
uint8_t knobLights;
|
||||
uint8_t lightPattern;
|
||||
// When tapping or long-pressing the macro key
|
||||
uint8_t macroClick;
|
||||
uint8_t macroHold;
|
||||
uint8_t macroPin[4];
|
||||
} sdvx_config_t;
|
||||
uint8_t joystickMode;
|
||||
} ATTR_PACKED sdvx_config_t;
|
||||
|
||||
#define CONFIG_BYTES sizeof(sdvx_config_t)
|
||||
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
#define USE_FLASH_DESCRIPTORS
|
||||
// #define USE_EEPROM_DESCRIPTORS
|
||||
// #define NO_INTERNAL_SERIAL
|
||||
#define FIXED_CONTROL_ENDPOINT_SIZE 8
|
||||
#define FIXED_CONTROL_ENDPOINT_SIZE 64
|
||||
// #define DEVICE_STATE_AS_GPIOR {Insert Value Here}
|
||||
#define FIXED_NUM_CONFIGURATIONS 1
|
||||
// #define CONTROL_ONLY_DEVICE
|
||||
|
||||
@@ -100,6 +100,36 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM InputsReport[] =
|
||||
HID_RI_REPORT_SIZE(8, 0x08),
|
||||
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE),
|
||||
HID_RI_END_COLLECTION(0),
|
||||
|
||||
/* Joystick report adjusted from HID_DESCRIPTOR_JOYSTICK */
|
||||
HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
|
||||
HID_RI_USAGE(8, 0x05), /* Game pad */
|
||||
HID_RI_COLLECTION(8, 0x01), /* Application */
|
||||
HID_RI_REPORT_ID(8, HID_REPORTID_JoystickReport),
|
||||
HID_RI_USAGE(8, 0x01), /* Pointer */
|
||||
HID_RI_COLLECTION(8, 0x00), /* Physical */
|
||||
HID_RI_USAGE(8, 0x30), /* X axis */
|
||||
HID_RI_USAGE(8, 0x31), /* Y axis */
|
||||
HID_RI_LOGICAL_MINIMUM(16, 0),
|
||||
HID_RI_LOGICAL_MAXIMUM(16, JOYSTICK_PPR-1),
|
||||
HID_RI_PHYSICAL_MINIMUM(16, -1),
|
||||
HID_RI_PHYSICAL_MAXIMUM(16, 1),
|
||||
HID_RI_REPORT_COUNT(8, 2), /* 2 axis */
|
||||
HID_RI_REPORT_SIZE(8, 8),
|
||||
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
|
||||
HID_RI_END_COLLECTION(0),
|
||||
HID_RI_USAGE_PAGE(8, 0x09), /* Button */
|
||||
HID_RI_USAGE_MINIMUM(8, 0x01), /* Button 1 */
|
||||
HID_RI_USAGE_MAXIMUM(8, SWITCH_COUNT), /* Button x */
|
||||
HID_RI_LOGICAL_MINIMUM(8, 0x00),
|
||||
HID_RI_LOGICAL_MAXIMUM(8, 0x01),
|
||||
HID_RI_REPORT_SIZE(8, 0x01),
|
||||
HID_RI_REPORT_COUNT(8, SWITCH_COUNT),
|
||||
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
|
||||
HID_RI_REPORT_SIZE(8, (SWITCH_COUNT % 8) ? (8 - (SWITCH_COUNT % 8)) : 0),
|
||||
HID_RI_REPORT_COUNT(8, 0x01),
|
||||
HID_RI_INPUT(8, HID_IOF_CONSTANT),
|
||||
HID_RI_END_COLLECTION(0)
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -1,38 +1,3 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2014.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for Descriptors.c.
|
||||
*/
|
||||
|
||||
#ifndef _DESCRIPTORS_H_
|
||||
#define _DESCRIPTORS_H_
|
||||
|
||||
@@ -102,6 +67,7 @@
|
||||
{
|
||||
HID_REPORTID_MouseReport = 0x01,
|
||||
HID_REPORTID_KeyboardReport = 0x02,
|
||||
HID_REPORTID_JoystickReport = 0x03,
|
||||
} HID_Report_IDs;
|
||||
|
||||
/* Macros: */
|
||||
@@ -111,15 +77,19 @@
|
||||
#define LED_EPADDR (ENDPOINT_DIR_IN | 4)
|
||||
|
||||
// the board only supports endpoints of 8, 16, 32 or 64 bytes
|
||||
#define ROUND_UP(bytes) (bytes <= 8 ? 8 : \
|
||||
bytes <= 16 ? 16 : \
|
||||
bytes <= 32 ? 32 : 64) // if it's larger than 64 bytes, you're out of luck
|
||||
#define ROUND_UP(bytes) ((bytes) <= 8 ? 8 : \
|
||||
(bytes) <= 16 ? 16 : \
|
||||
(bytes) <= 32 ? 32 : 64) // if it's larger than 64 bytes, you're out of luck
|
||||
|
||||
// acts like a union, mouse is 8 bytes
|
||||
#define INPUTS_EPSIZE ROUND_UP(MAX(SWITCH_COUNT + 2, 8))
|
||||
#define LED_EPSIZE ROUND_UP(LED_TOTAL_COUNT)
|
||||
/* acts like a union
|
||||
* keyboard is switches + modifiers and reserved byte
|
||||
* mouse is 8 bytes
|
||||
* joystick is 2 axis + buttons as bitmask
|
||||
* add 1 for report ID */
|
||||
#define INPUTS_EPSIZE ROUND_UP(1+MAX(MAX(SWITCH_COUNT + 2, 8), 3 + SWITCH_COUNT/8))
|
||||
#define LED_EPSIZE ROUND_UP(LED_TOTAL_COUNT)
|
||||
// ignoring board limits, bulk endpoints MUST be 8, 16, 32 or 64 bytes
|
||||
#define CONFIG_EPSIZE ROUND_UP(COMMAND_BYTES)
|
||||
#define CONFIG_EPSIZE ROUND_UP(COMMAND_BYTES+1)
|
||||
|
||||
/* Function Prototypes: */
|
||||
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
|
||||
|
||||
@@ -20,6 +20,21 @@
|
||||
// How long to wait before moving to internal lighting
|
||||
#define HID_LED_TIMEOUT 2000
|
||||
|
||||
// If I add more buttons with the macro key I don't need to care
|
||||
#if SWITCH_COUNT <= 8
|
||||
#define SWITCH_BITMASK_UINT uint8_t
|
||||
#elif SWITCH_COUNT <= 16
|
||||
#define SWITCH_BITMASK_UINT uint16_t
|
||||
#else
|
||||
#error TOO MANY SWITCHES
|
||||
#endif
|
||||
typedef struct
|
||||
{
|
||||
int8_t X; // VOL-L
|
||||
int8_t Y; // VOL-R
|
||||
SWITCH_BITMASK_UINT Buttons; // bitmask
|
||||
} Joystick_Report_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t Modifier; // Keyboard modifier byte indicating pressed modifier keys (\c HID_KEYBOARD_MODIFER_* masks)
|
||||
@@ -33,12 +48,11 @@ typedef struct
|
||||
uint8_t btFx[6];
|
||||
} LED_Report_t;
|
||||
|
||||
/** Buffer to hold the previously generated Keyboard HID report, for comparison purposes inside the HID class driver. */
|
||||
static uint8_t PrevInputsHIDReportBuffer[MAX(sizeof(Keyboard_Report_t), sizeof(USB_MouseReport_Data_t))];
|
||||
static uint8_t PrevLEDHIDReportBuffer[sizeof(LED_Report_t)];
|
||||
|
||||
static uint8_t sendKeyboard = 0;
|
||||
static uint8_t updateLEDs = 1;
|
||||
static int8_t joystickKnobs[2] = {0, 0};
|
||||
|
||||
/** LUFA HID Class driver interface configuration and state information. This structure is
|
||||
* passed to all HID Class driver functions, so that multiple instances of the same class
|
||||
@@ -55,8 +69,8 @@ USB_ClassInfo_HID_Device_t Inputs_HID_Interface =
|
||||
.Size = INPUTS_EPSIZE,
|
||||
.Banks = 1,
|
||||
},
|
||||
.PrevReportINBuffer = PrevInputsHIDReportBuffer,
|
||||
.PrevReportINBufferSize = sizeof(PrevInputsHIDReportBuffer),
|
||||
.PrevReportINBuffer = NULL,
|
||||
.PrevReportINBufferSize = MAX(MAX(sizeof(Keyboard_Report_t), sizeof(Joystick_Report_t)), sizeof(USB_MouseReport_Data_t)),
|
||||
},
|
||||
};
|
||||
|
||||
@@ -247,51 +261,92 @@ bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDIn
|
||||
{
|
||||
if(ReportType != HID_REPORT_ITEM_In || HIDInterfaceInfo != &Inputs_HID_Interface) {
|
||||
*ReportSize = 0;
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
sendKeyboard ^= 1;
|
||||
if (sendKeyboard) {
|
||||
// nothing requested so let's make our own
|
||||
if(*ReportID == 0) {
|
||||
// Always runs because we can have KB macros even with joystick
|
||||
sendKeyboard ^= 1;
|
||||
if(sendKeyboard) {
|
||||
*ReportID = HID_REPORTID_KeyboardReport;
|
||||
} else {
|
||||
if(sdvxConfig.joystickMode) {
|
||||
*ReportID = HID_REPORTID_JoystickReport;
|
||||
} else {
|
||||
*ReportID = HID_REPORTID_MouseReport;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(*ReportID == HID_REPORTID_KeyboardReport) {
|
||||
Keyboard_Report_t* KeyboardReport = (Keyboard_Report_t*)ReportData;
|
||||
|
||||
// Only the first 4 bytes are read by bemanitools, so let's use the first
|
||||
uint8_t macroUpdated = macro_make_report(&KeyboardReport->KeyCode[0]);
|
||||
update_switches();
|
||||
|
||||
if(!switchesChanged && !macroUpdated) {
|
||||
if(!macroUpdated && (sdvxConfig.joystickMode || !switchesChanged)) {
|
||||
*ReportSize = 0;
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// NOTE: using SWITCH_COUNT-1 so we don't write the report for the macro pin
|
||||
for(uint8_t i = 0; i < SWITCH_COUNT-1; i++) {
|
||||
// i+1 to take care of the shift from above
|
||||
KeyboardReport->KeyCode[i+1] = switches[i].state ? sdvxConfig.switches[i] : 0;
|
||||
switches[i].lastReport = switches[i].state;
|
||||
// Update blinkenlights
|
||||
if(switches[i].state) {
|
||||
//if(sdvxConfig.ledsOn) {
|
||||
// // TODO
|
||||
//}
|
||||
if(!sdvxConfig.joystickMode) {
|
||||
// NOTE: using SWITCH_COUNT-1 so we don't write the report for the macro pin
|
||||
for(uint8_t i = 0; i < SWITCH_COUNT-1; i++) {
|
||||
// i+1 to take care of the shift from above
|
||||
KeyboardReport->KeyCode[i+1] = switches[i].state ? sdvxConfig.switches[i] : 0;
|
||||
switches[i].lastReport = switches[i].state;
|
||||
}
|
||||
switchesChanged = 0;
|
||||
}
|
||||
|
||||
*ReportID = HID_REPORTID_KeyboardReport;
|
||||
|
||||
*ReportSize = sizeof(Keyboard_Report_t);
|
||||
|
||||
switchesChanged = 0;
|
||||
} else {
|
||||
USB_MouseReport_Data_t* MouseReport = (USB_MouseReport_Data_t*)ReportData;
|
||||
|
||||
MouseReport->X = encoder_get(0);
|
||||
MouseReport->Y = encoder_get(1);
|
||||
|
||||
led_knobs_update(MouseReport->X, MouseReport->Y);
|
||||
|
||||
int8_t x = encoder_get(0);
|
||||
int8_t y = encoder_get(1);
|
||||
led_knobs_update(x, y);
|
||||
encoder_set(0, 0);
|
||||
encoder_set(1, 0);
|
||||
|
||||
if(*ReportID == HID_REPORTID_MouseReport) {
|
||||
if(x == 0 && y == 0) {
|
||||
*ReportSize = 0;
|
||||
return true;
|
||||
}
|
||||
USB_MouseReport_Data_t* MouseReport = (USB_MouseReport_Data_t*)ReportData;
|
||||
|
||||
MouseReport->X = x;
|
||||
MouseReport->Y = y;
|
||||
|
||||
*ReportID = HID_REPORTID_MouseReport;
|
||||
*ReportSize = sizeof(USB_MouseReport_Data_t);
|
||||
*ReportSize = sizeof(USB_MouseReport_Data_t);
|
||||
} else { // joystick
|
||||
if(x == 0 && y == 0 && !switchesChanged) {
|
||||
*ReportSize = 0;
|
||||
return true;
|
||||
}
|
||||
Joystick_Report_t* JoyReport = (Joystick_Report_t*)ReportData;
|
||||
|
||||
joystickKnobs[0] += x;
|
||||
joystickKnobs[1] += y;
|
||||
for(uint8_t i = 0; i < 2; i++) {
|
||||
if(joystickKnobs[i] < 0)
|
||||
joystickKnobs[i] += JOYSTICK_PPR;
|
||||
if(joystickKnobs[i] >= JOYSTICK_PPR)
|
||||
joystickKnobs[i] -= JOYSTICK_PPR;
|
||||
}
|
||||
|
||||
JoyReport->X = joystickKnobs[0];
|
||||
JoyReport->Y = joystickKnobs[1];
|
||||
|
||||
// going backwards to make bitshifts nice
|
||||
for(int8_t i = SWITCH_COUNT-1; i >= 0; i--) {
|
||||
JoyReport->Buttons <<= 1;
|
||||
JoyReport->Buttons |= switches[i].state;
|
||||
switches[i].lastReport = switches[i].state;
|
||||
}
|
||||
switchesChanged = 0;
|
||||
|
||||
*ReportSize = sizeof(Joystick_Report_t);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -376,6 +431,8 @@ void EVENT_USB_Device_ControlRequest(void)
|
||||
/** Event handler for the USB device Start Of Frame event. */
|
||||
void EVENT_USB_Device_StartOfFrame(void)
|
||||
{
|
||||
update_switches();
|
||||
macro_on_frame(&switches[SWITCH_COUNT-1]);
|
||||
HID_Device_MillisecondElapsed(&Inputs_HID_Interface);
|
||||
HID_Device_MillisecondElapsed(&LED_HID_Interface);
|
||||
|
||||
@@ -389,8 +446,6 @@ void EVENT_USB_Device_StartOfFrame(void)
|
||||
updateLEDs = 1;
|
||||
}
|
||||
|
||||
macro_on_frame(&switches[SWITCH_COUNT-1]);
|
||||
|
||||
for(int i = 0; i < SWITCH_COUNT; i++) {
|
||||
if(switches[i].debounce) {
|
||||
switches[i].debounce--;
|
||||
|
||||
@@ -1,38 +1,3 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2014.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for Keyboard.c.
|
||||
*/
|
||||
|
||||
#ifndef _KEYBOARD_H_
|
||||
#define _KEYBOARD_H_
|
||||
|
||||
|
||||
Reference in New Issue
Block a user