Skip to content

Commit

Permalink
convert core GPIO pin mappings from button-to-pin to pin-to-action (O…
Browse files Browse the repository at this point in the history
…penStickCommunity#504)

* convert core GPIO pin mappings from button2pin to pin2action

this changes the core board config and gamepad behavior to be that the
settings/user configures what each pin does, rather than the old
behavior which configures what pin each button is assigned to. this
allows for the new configuration to have one canonical location for what
each of the pins does, and removes the limitation that a button can only
normally be activated by one pin --- now it is trivial to assign many
pins to take the same action

"actions" are all button presses right now, but they may be other things
in the future as this branch expands. this is just the core
functionality and migration code for now, further changes (removing
extra input addon, refactoring DDI, maybe refactoring the sliders,
working the profiles into this scheme, etc.) to come

* remove the extra button addon, it is unnecessary now

* unset deprecated pin mappings after migration

* unset the extra button addon pin after migration

* fix the processing of the aux state/Fn button

* renumber the non-managed pin enum entries

motivation for this is the migration sets everything to NONE anyway, so
the 0 value isn't super important to us, and protobuf by convention
seems to use the lowest value as a default (e.g. in the python GUI
editor), so setting that to NONE is idiomatic in both cases

* fix the unsetting of the extra input addon after migrating

* convert DDI pins to gpioMappings

the rest of the DDI settings remain untouched, and the whole addon is
basically where it always was, this just allows for centralization in
the new GPIO mappings

* add TODO for fixing the pin UI

* fix the checking of the DDI masks

* convert get/setPinMappings API to match refactor

* "hardcode" the writing of 30 pins to JSON

ArduinoJson retains the reference to the string until write time, so it
was only actually publishing the value for pin29

* convert the JS slider pins to the centralized config

there's not much left of the addon other than the config for what to do
when nothing is held, so, this is a great candidate for getting folded
into core

* rename default JS mode option for consistency w/SOCD slider

* preliminary SOCD slider port to gpioMappings

* correct JS slider migration to refer to proper config/defines

* correct SOCD slider migration by referring to proper settings

* Global pin state action example using zustand

* Export baseUrl

* Pin to action ui playground, using global state with zustand

* Hide som actions from dropdown. make the select disabled if action is set from board

* Add a form for semantics

* Add translation for labels, dynamic columns.

* Remove pin -> action PoC from playground

* Make savePins return promise

* Replace pin mapping with pin -> action

* Remove unused handler in usePinStore

* remove DDI pins from addon page, point at Pin Mapping page

* add more add-on pin usages to the UI

* flag miscellaneous addon pins as ASSIGNED in migration

* when saving addons/display pins in web config, mark them ASSIGNED

* don't allow profiles to touch RESERVED/ASSIGNED_TO_ADDON

this is partially a problem now (we shouldn't let a profile assign a pin
that is normally reserved or on a addon), and partially a problem in the
future (we shouldn't let a profile SET a pin to reserved/for an addon),
when the profiles are refactored to use gpio mappings

* Add better typing for usePinStore

* - Create a new Capture button component that is reusable for any input.
- Make new pin mapping handle labels for all input modes including swapTpShareLabels

* don't include ASSIGNED_TO_ADDON in getUsedPins

temporary measure as the addons' validation needs reworking to support
a response that includes their own pins

* don't allow setPinMappings to set/change addon/reserved pins

* addons API shouldn't refer to DDI pins anymore now that they're "core"

* remove unused API stuff from the dev server JSON

* DRY on the simple protobuf-or-boardconfig pin migrations

this also removes the protobuf isValidPin(foo) check and replaces it
with a has_ + a nested check that it's between 0 and 29, so that if a
user set a button to -1, we don't fallback to the BoardConfig.h, which
would clobber their intentional unmapping

* set ASSIGNED_TO_ADDON -> NONE if the new addon pin is invalid

* un-ASSIGNED_TO_ADDON the Dminus pins when unsetting the Dplus pins

* Remove double call on context

* Remove useState for selectedBoard as it's only set once

* Remove unused imports

* Remove setLoading on getPinMappings as this creates race conditions, remove log

* Map new pin actions to button mappings for profile settings

* Remove unused lodash import

* Remove export

* remove unused EXTRA_BUTTON_ENABLED define

* track when migrations have occurred

I believe that it would be possible, without this history, for someone
to unmap certain gpioMappings (or hotkeys) for intentional reasons and
then accidentally trigger a re-conversion of the old BoardConfig.h
values, meaning they could never unmap certain hotkeys or gpioMappings.
this bool avoids that by only running the migration code once ever

maybe it makes startup faster too, idk

* remove unnecessary save()s in slider addons

* define types for a pin and a gamepad mask

---------

Co-authored-by: ian <[email protected]>
  • Loading branch information
2 people authored and jack2game committed Nov 1, 2023
1 parent 3d45ad5 commit 8cf55b5
Show file tree
Hide file tree
Showing 40 changed files with 1,721 additions and 1,297 deletions.
3 changes: 1 addition & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,6 @@ src/addons/bootsel_button.cpp
src/addons/focus_mode.cpp
src/addons/buzzerspeaker.cpp
src/addons/dualdirectional.cpp
src/addons/extra_button.cpp
src/addons/keyboard_host.cpp
src/addons/i2canalog1219.cpp
src/addons/jslider.cpp
Expand Down Expand Up @@ -222,4 +221,4 @@ install(FILES
if (NOT (DEFINED ENV(CI)) AND (EXISTS ${CMAKE_SOURCE_DIR}/modules/Custom.cmake))
message(STATUS "Found custom script.")
include(${CMAKE_SOURCE_DIR}/modules/Custom.cmake)
endif()
endif()
1 change: 0 additions & 1 deletion configs/MavercadeKeebfighter/BoardConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,6 @@

// Extra Button Add-on setting

#define EXTRA_BUTTON_ENABLED 1
#define EXTRA_BUTTON_MASK GAMEPAD_MASK_DU // 0 means none, get other mask from GamepadState.h
// For directions, use GAMEPAD_MASK_DU, GAMEPAD_MASK_DD, GAMEPAD_MASK_DL and GAMEPAD_MASK_DR
#define EXTRA_BUTTON_PIN 1
Expand Down
1 change: 0 additions & 1 deletion configs/OpenCore0WASD/BoardConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,6 @@
#define BOOTSEL_BUTTON_MASK 0 // 0 means none, get other mask from GamepadState.h

// Extra Button Add-on setting
#define EXTRA_BUTTON_ENABLED 1
#define EXTRA_BUTTON_MASK GAMEPAD_MASK_DU // 0 means none, get other mask from GamepadState.h
// For directions, use GAMEPAD_MASK_DU, GAMEPAD_MASK_DD, GAMEPAD_MASK_DL and GAMEPAD_MASK_DR
#define EXTRA_BUTTON_PIN 13
Expand Down
8 changes: 4 additions & 4 deletions headers/addons/dualdirectional.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,12 @@ class DualDirectionalInput : public GPAddon {
DpadDirection lastDualUD; // Dual Last Up-Down
DpadDirection lastDualLR; // Gamepad Last Left-Right
uint32_t dpadTime[4];
uint8_t pinDualDirDown;
uint8_t pinDualDirUp;
uint8_t pinDualDirLeft;
uint8_t pinDualDirRight;
uint8_t combineMode;
DpadMode dpadMode;
GamepadButtonMapping *mapDpadUp;
GamepadButtonMapping *mapDpadDown;
GamepadButtonMapping *mapDpadLeft;
GamepadButtonMapping *mapDpadRight;
};

#endif // _DualDirectional_H
26 changes: 0 additions & 26 deletions headers/addons/extra_button.h

This file was deleted.

7 changes: 6 additions & 1 deletion headers/addons/jslider.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "gpaddon.h"

#include "GamepadEnums.h"
#include "types.h"

#ifndef JSLIDER_ENABLED
#define JSLIDER_ENABLED 0
Expand Down Expand Up @@ -45,6 +46,10 @@ class JSliderInput : public GPAddon {
DpadMode dpadState; // Saved locally for debounce
DpadMode dDebState; // Debounce JSlider State
uint32_t uDebTime; // Debounce JSlider Time

Mask_t dpModeMask = 0;
Mask_t lsModeMask = 0;
Mask_t rsModeMask = 0;
};

#endif // _JSlider_H_
#endif // _JSlider_H_
14 changes: 8 additions & 6 deletions headers/addons/slider_socd.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define _SliderSOCD_H

#include "gpaddon.h"
#include "types.h"

#include "GamepadEnums.h"

Expand Down Expand Up @@ -45,11 +46,12 @@ class SliderSOCDInput : public GPAddon {
SOCDMode socdState; // Saved locally for debounce
SOCDMode dDebState; // Debounce SliderSOCD State
uint32_t uDebTime; // Debounce SliderSOCD Time
SOCDMode sliderSOCDModeOne;
SOCDMode sliderSOCDModeTwo;
SOCDMode sliderSOCDModeDefault;
uint8_t pinSliderSOCDOne;
uint8_t pinSliderSOCDTwo;

Mask_t upPrioModeMask = 0;
Mask_t neutralModeMask = 0;
Mask_t secondInputModeMask = 0;
Mask_t firstInputModeMask = 0;
Mask_t bypassModeMask = 0;
};

#endif // _SliderSOCD_H_
#endif // _SliderSOCD_H_
25 changes: 4 additions & 21 deletions headers/gamepad.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define _GAMEPAD_H_

#include "BoardConfig.h"
#include "types.h"
#include <string.h>

#include "enums.pb.h"
Expand All @@ -25,31 +26,13 @@ extern uint64_t getMicro();

struct GamepadButtonMapping
{
GamepadButtonMapping(uint8_t p, uint16_t bm) :
pin(p < NUM_BANK0_GPIOS ? p : 0xff),
pinMask(p < NUM_BANK0_GPIOS? (1 << p) : 0),
GamepadButtonMapping(Mask_t bm) :
pinMask(0),
buttonMask(bm)
{}

uint8_t pin;
uint32_t pinMask;
const uint16_t buttonMask;

inline void setPin(uint8_t p)
{
if (p < NUM_BANK0_GPIOS)
{
pin = p;
pinMask = 1 << p;
}
else
{
pin = 0xff;
pinMask = 0;
}
}

bool isAssigned() const { return pin != 0xff; }
};

#define GAMEPAD_DIGITAL_INPUT_COUNT 18 // Total number of buttons, including D-pad
Expand Down Expand Up @@ -173,7 +156,7 @@ class Gamepad {
GamepadButtonMapping *mapButtonR3;
GamepadButtonMapping *mapButtonA1;
GamepadButtonMapping *mapButtonA2;
GamepadButtonMapping **gamepadMappings;
GamepadButtonMapping *mapButtonFn;

inline static const SOCDMode resolveSOCDMode(const GamepadOptions& options) {
return (options.socdMode == SOCD_MODE_BYPASS &&
Expand Down
10 changes: 6 additions & 4 deletions headers/storagemanager.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,19 +35,20 @@ class Storage {
GamepadOptions& getGamepadOptions() { return config.gamepadOptions; }
HotkeyOptions& getHotkeyOptions() { return config.hotkeyOptions; }
ForcedSetupOptions& getForcedSetupOptions() { return config.forcedSetupOptions; }
PinMappings& getPinMappings() { return config.pinMappings; }
PinMappings& getDeprecatedPinMappings() { return config.deprecatedPinMappings; }
GpioMappings& getGpioMappings() { return config.gpioMappings; }
GpioAction** getGpioMappingsArray() { return gpioMappingsArray; }
KeyboardMapping& getKeyboardMapping() { return config.keyboardMapping; }
DisplayOptions& getDisplayOptions() { return config.displayOptions; }
DisplayOptions& getPreviewDisplayOptions() { return previewDisplayOptions; }
LEDOptions& getLedOptions() { return config.ledOptions; }
AddonOptions& getAddonOptions() { return config.addonOptions; }
AnimationOptions_Proto& getAnimationOptions() { return config.animationOptions; }
ProfileOptions& getProfileOptions() { return config.profileOptions; }
GpioAction* getProfilePinMappings() { return functionalPinMappings; }

bool save();

PinMappings& getProfilePinMappings();

// Perform saves that were enqueued from core1
void performEnqueuedSaves();

Expand Down Expand Up @@ -83,7 +84,8 @@ class Storage {
critical_section_t animationOptionsCs;
uint32_t animationOptionsCrc = 0;
AnimationOptions animationOptionsToSave = {};
PinMappings* functionalPinMappings = nullptr;
GpioAction functionalPinMappings[NUM_BANK0_GPIOS];
GpioAction* gpioMappingsArray[NUM_BANK0_GPIOS];
};

#endif
13 changes: 13 additions & 0 deletions headers/types.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/*
* SPDX-License-Identifier: MIT
* SPDX-FileCopyrightText: Copyright (c) 2023 Brian S. Stephan <[email protected]>
*/

#ifndef TYPES_H_
#define TYPES_H_

// common types
#define Pin_t int32_t // signed to accommodate for -1
#define Mask_t uint32_t

#endif
72 changes: 57 additions & 15 deletions proto/config.proto
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,40 @@ message PinMappings
optional int32 pinButtonFn = 19;
}

message GpioMappings
{
optional GpioAction pin00 = 1;
optional GpioAction pin01 = 2;
optional GpioAction pin02 = 3;
optional GpioAction pin03 = 4;
optional GpioAction pin04 = 5;
optional GpioAction pin05 = 6;
optional GpioAction pin06 = 7;
optional GpioAction pin07 = 8;
optional GpioAction pin08 = 9;
optional GpioAction pin09 = 10;
optional GpioAction pin10 = 11;
optional GpioAction pin11 = 12;
optional GpioAction pin12 = 13;
optional GpioAction pin13 = 14;
optional GpioAction pin14 = 15;
optional GpioAction pin15 = 16;
optional GpioAction pin16 = 17;
optional GpioAction pin17 = 18;
optional GpioAction pin18 = 19;
optional GpioAction pin19 = 20;
optional GpioAction pin20 = 21;
optional GpioAction pin21 = 22;
optional GpioAction pin22 = 23;
optional GpioAction pin23 = 24;
optional GpioAction pin24 = 25;
optional GpioAction pin25 = 26;
optional GpioAction pin26 = 27;
optional GpioAction pin27 = 28;
optional GpioAction pin28 = 29;
optional GpioAction pin29 = 30;
}


message AlternativePinMappings
{
Expand Down Expand Up @@ -313,23 +347,23 @@ message SliderOptions
{
optional bool enabled = 1;

optional int32 pinSliderOne = 2;
optional int32 pinSliderTwo = 3;
optional DpadMode modeOne = 4;
optional DpadMode modeTwo = 5;
optional DpadMode modeZero = 6;
optional int32 deprecatedPinSliderOne = 2;
optional int32 deprecatedPinSliderTwo = 3;
optional DpadMode deprecatedModeOne = 4;
optional DpadMode deprecatedModeTwo = 5;
optional DpadMode modeDefault = 6;
}

message SOCDSliderOptions
{
optional bool enabled = 1;

optional int32 pinOne = 2;
optional int32 pinTwo = 3;
optional int32 deprecatedPinOne = 2;
optional int32 deprecatedPinTwo = 3;

optional SOCDMode modeDefault = 4;
optional SOCDMode modeOne = 5;
optional SOCDMode modeTwo = 6;
optional SOCDMode deprecatedModeOne = 5;
optional SOCDMode deprecatedModeTwo = 6;
}

message ReverseOptions
Expand Down Expand Up @@ -360,10 +394,10 @@ message DualDirectionalOptions
{
optional bool enabled = 1;

optional int32 upPin = 2;
optional int32 downPin = 3;
optional int32 leftPin = 4;
optional int32 rightPin = 5;
optional int32 deprecatedUpPin = 2;
optional int32 deprecatedDownPin = 3;
optional int32 deprecatedLeftPin = 4;
optional int32 deprecatedRightPin = 5;

optional DpadMode dpadMode = 6;
optional uint32 combineMode = 7;
Expand Down Expand Up @@ -648,7 +682,7 @@ message AddonOptions
optional AnalogADS1219Options analogADS1219Options = 7;
optional DualDirectionalOptions dualDirectionalOptions = 8;
optional BuzzerOptions buzzerOptions = 9;
optional ExtraButtonOptions extraButtonOptions = 10;
optional ExtraButtonOptions deprecatedExtraButtonOptions = 10;
optional PlayerNumberOptions playerNumberOptions = 11;
optional PS4Options ps4Options = 12 [(nanopb).disallow_export = true];
optional WiiOptions wiiOptions = 13;
Expand All @@ -661,13 +695,19 @@ message AddonOptions
optional MacroOptions macroOptions = 20;
}

message MigrationHistory
{
optional bool hotkeysMigrated = 1 [default = false];
optional bool gpioMappingsMigrated = 2 [default = false];
}

message Config
{
optional string boardVersion = 1 [(nanopb).max_length = 31];

optional GamepadOptions gamepadOptions = 2;
optional HotkeyOptions hotkeyOptions = 3;
optional PinMappings pinMappings = 4;
optional PinMappings deprecatedPinMappings = 4;
optional KeyboardMapping keyboardMapping = 5;
optional DisplayOptions displayOptions = 6;
optional LEDOptions ledOptions = 7;
Expand All @@ -677,4 +717,6 @@ message Config
optional ProfileOptions profileOptions = 11;

optional string boardConfig = 12 [(nanopb).max_length = 63];
optional GpioMappings gpioMappings = 13;
optional MigrationHistory migrations = 14;
}
42 changes: 42 additions & 0 deletions proto/enums.proto
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,48 @@ enum SOCDMode
SOCD_MODE_BYPASS = 4; // U+D=UD, L+R=LR (No cleaning applied)
}

enum GpioAction
{
option (nanopb_enumopt).long_names = false;

// the lowest value is the default, which should be NONE;
// reserving some numbers in case we need more not-mapped type values
NONE = -10;
RESERVED = -5;
ASSIGNED_TO_ADDON = 0;
BUTTON_PRESS_UP = 1;
BUTTON_PRESS_DOWN = 2;
BUTTON_PRESS_LEFT = 3;
BUTTON_PRESS_RIGHT = 4;
BUTTON_PRESS_B1 = 5;
BUTTON_PRESS_B2 = 6;
BUTTON_PRESS_B3 = 7;
BUTTON_PRESS_B4 = 8;
BUTTON_PRESS_L1 = 9;
BUTTON_PRESS_R1 = 10;
BUTTON_PRESS_L2 = 11;
BUTTON_PRESS_R2 = 12;
BUTTON_PRESS_S1 = 13;
BUTTON_PRESS_S2 = 14;
BUTTON_PRESS_A1 = 15;
BUTTON_PRESS_A2 = 16;
BUTTON_PRESS_L3 = 17;
BUTTON_PRESS_R3 = 18;
BUTTON_PRESS_FN = 19;
BUTTON_PRESS_DDI_UP = 20;
BUTTON_PRESS_DDI_DOWN = 21;
BUTTON_PRESS_DDI_LEFT = 22;
BUTTON_PRESS_DDI_RIGHT = 23;
SUSTAIN_DP_MODE_DP = 24;
SUSTAIN_DP_MODE_LS = 25;
SUSTAIN_DP_MODE_RS = 26;
SUSTAIN_SOCD_MODE_UP_PRIO = 27;
SUSTAIN_SOCD_MODE_NEUTRAL = 28;
SUSTAIN_SOCD_MODE_SECOND_WIN = 29;
SUSTAIN_SOCD_MODE_FIRST_WIN = 30;
SUSTAIN_SOCD_MODE_BYPASS = 31;
}

enum GamepadHotkey
{
option (nanopb_enumopt).long_names = false;
Expand Down
Loading

0 comments on commit 8cf55b5

Please sign in to comment.