Skip to content

Commit

Permalink
Keyboard Volume Dial - Rotary Encoder Extension (#1274)
Browse files Browse the repository at this point in the history
* Testing Volume Dial using GPEvents

* Missed an include

* Add volume up / down reset on usb report complete (this should be a built-in in input drivers). Also fixed a silly web config thing

* Update Rotary.tsx

* Update Rotary.jsx
  • Loading branch information
arntsonl authored Jan 25, 2025
1 parent ffca955 commit 87f2376
Show file tree
Hide file tree
Showing 6 changed files with 40 additions and 2 deletions.
3 changes: 3 additions & 0 deletions headers/drivers/keyboard/KeyboardDriver.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include "gpdriver.h"
#include "drivers/keyboard/KeyboardDescriptors.h"
#include "eventmanager.h"

class KeyboardDriver : public GPDriver {
public:
Expand All @@ -25,6 +26,7 @@ class KeyboardDriver : public GPDriver {
virtual const uint8_t * get_descriptor_device_qualifier_cb();
virtual uint16_t GetJoystickMidValue();
virtual USBListener * get_usb_auth_listener() { return nullptr; }
void handleEncoder(GPEvent* e); // for Volume - rotary encoder
private:
void releaseAllKeys(void);
void pressKey(uint8_t code);
Expand All @@ -33,6 +35,7 @@ class KeyboardDriver : public GPDriver {
uint8_t last_report[CFG_TUD_ENDPOINT0_SIZE] = { };
uint16_t last_report_size;
KeyboardReport keyboardReport;
int8_t volumeChange;
};

#endif // _KEYBOARD_DRIVER_H_
1 change: 1 addition & 0 deletions proto/enums.proto
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,7 @@ enum RotaryEncoderPinMode
ENCODER_MODE_RIGHT_TRIGGER = 6;
ENCODER_MODE_DPAD_X = 7;
ENCODER_MODE_DPAD_Y = 8;
ENCODER_MODE_VOLUME = 9;
};

enum ReactiveLEDMode
Expand Down
2 changes: 2 additions & 0 deletions src/addons/rotaryencoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@ void RotaryEncoderInput::process()
int8_t axis = mapEncoderValueDPad(i, encoderValues[i], encoderMap[i].pulsesPerRevolution);
dpadUp = (axis == 1);
dpadDown = (axis == -1);
} else if (encoderMap[i].mode == ENCODER_MODE_VOLUME) {
// Prevents NONE kick-out, do nothing for now but rely on GP events
}

if ((encoderValues[i] - prevValues[i]) != 0) {
Expand Down
30 changes: 30 additions & 0 deletions src/drivers/keyboard/KeyboardDriver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
#include "drivers/shared/driverhelper.h"
#include "drivers/hid/HIDDescriptors.h"

#include "eventmanager.h"

void KeyboardDriver::initialize() {
keyboardReport = {
.keycode = { 0 },
Expand All @@ -20,6 +22,10 @@ void KeyboardDriver::initialize() {
.xfer_cb = hidd_xfer_cb,
.sof = NULL
};

// Handle Volume for Rotary Encoder
EventManager::getInstance().registerEventHandler(GP_EVENT_ENCODER_CHANGE, GPEVENT_CALLBACK(this->handleEncoder(event)));
volumeChange = 0; // no change
}

uint8_t KeyboardDriver::getModifier(uint8_t code) {
Expand Down Expand Up @@ -87,6 +93,12 @@ void KeyboardDriver::process(Gamepad * gamepad) {
if(gamepad->pressedE11()) { pressKey(keyboardMapping.keyButtonE11); }
if(gamepad->pressedE12()) { pressKey(keyboardMapping.keyButtonE12); }

if( volumeChange > 0 ) {
pressKey(KEYBOARD_MULTIMEDIA_VOLUME_UP);
} else if ( volumeChange < 0 ) {
pressKey(KEYBOARD_MULTIMEDIA_VOLUME_DOWN);
}

// Wake up TinyUSB device
if (tud_suspended())
tud_remote_wakeup();
Expand All @@ -109,6 +121,13 @@ void KeyboardDriver::process(Gamepad * gamepad) {
if ( tud_hid_report(keyboardReport.reportId, keyboard_report_payload, keyboard_report_size) ) {
memcpy(last_report, keyboard_report_payload, keyboard_report_size);
last_report_size = keyboard_report_size;

// Adjust volume on success
if( volumeChange > 0 ) {
volumeChange--;
} else if ( volumeChange < 0 ) {
volumeChange++;
}
}
}
}
Expand Down Expand Up @@ -174,3 +193,14 @@ const uint8_t * KeyboardDriver::get_descriptor_device_qualifier_cb() {
uint16_t KeyboardDriver::GetJoystickMidValue() {
return HID_JOYSTICK_MID << 8;
}

void KeyboardDriver::handleEncoder(GPEvent* e) {
GPEncoderChangeEvent * encoderEvent = (GPEncoderChangeEvent*)e;
if ( encoderEvent->direction == 1 ) {
// volume up
volumeChange++;
} else if ( encoderEvent->direction == -1 ) {
// volume down
volumeChange--;
}
}
5 changes: 3 additions & 2 deletions www/src/Addons/Rotary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ const ENCODER_MODES = [
{ label: 'encoder-mode-right-trigger', value: 6 },
{ label: 'encoder-mode-dpad-x', value: 7 },
{ label: 'encoder-mode-dpad-y', value: 8 },
{ label: 'encoder-mode-volume', value: 9 },
];

const ENCODER_MULTIPLES = [
Expand All @@ -43,7 +44,7 @@ export const rotaryScheme = {
.number()
.required()
.label('Rotary Encoder Add-On Enabled'),
encoderOneEnabled: yup.number().required().label('Encoder One Enabled'),
encoderOneEnabled: yup.boolean().required().label('Encoder One Enabled'),
encoderOnePinA: yup
.number()
.label('Encoder One Pin A')
Expand All @@ -65,7 +66,7 @@ export const rotaryScheme = {
.required()
.label('Encoder One Allow Wrap Around'),
encoderOneMultiplier: yup.number().label('Encoder One Multiplier').required(),
encoderTwoEnabled: yup.number().required().label('Encoder Two Enabled'),
encoderTwoEnabled: yup.boolean().required().label('Encoder Two Enabled'),
encoderTwoPinA: yup
.number()
.label('Encoder Two Pin A')
Expand Down
1 change: 1 addition & 0 deletions www/src/Locales/en/Addons/Rotary.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,5 @@ export default {
'encoder-mode-right-trigger': 'Right Trigger',
'encoder-mode-dpad-x': 'D-Pad Left/Right',
'encoder-mode-dpad-y': 'D-Pad Up/Down',
'encoder-mode-volume': 'Volume (Keyboard Only)',
};

0 comments on commit 87f2376

Please sign in to comment.