Skip to content
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

Dual rotary encoder support #879

Merged
Merged
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
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ src/addons/playernum.cpp
src/addons/playerleds.cpp
src/addons/ps4mode.cpp
src/addons/pspassthrough.cpp
src/addons/rotaryencoder.cpp
src/addons/reverse.cpp
src/addons/turbo.cpp
src/addons/slider_socd.cpp
Expand Down
128 changes: 128 additions & 0 deletions headers/addons/rotaryencoder.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
#ifndef _ROTARYENCODER_H
#define _ROTARYENCODER_H

#include "gpaddon.h"

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

#ifndef ROTARY_ENCODER_ENABLED
#define ROTARY_ENCODER_ENABLED 0
#endif

#ifndef ENCODER_ONE_ENABLED
#define ENCODER_ONE_ENABLED 0
#endif

#ifndef ENCODER_ONE_PPR
#define ENCODER_ONE_PPR 24
#endif

#ifndef ENCODER_ONE_PIN_A
#define ENCODER_ONE_PIN_A -1
#endif

#ifndef ENCODER_ONE_PIN_B
#define ENCODER_ONE_PIN_B -1
#endif

#ifndef ENCODER_ONE_MODE
#define ENCODER_ONE_MODE ENCODER_MODE_NONE
#endif

#ifndef ENCODER_ONE_WRAP
#define ENCODER_ONE_WRAP 0
#endif

#ifndef ENCODER_ONE_MULTIPLIER
#define ENCODER_ONE_MULTIPLIER 1
#endif

#ifndef ENCODER_TWO_ENABLED
#define ENCODER_TWO_ENABLED 0
#endif

#ifndef ENCODER_TWO_PPR
#define ENCODER_TWO_PPR 24
#endif

#ifndef ENCODER_TWO_PIN_A
#define ENCODER_TWO_PIN_A -1
#endif

#ifndef ENCODER_TWO_PIN_B
#define ENCODER_TWO_PIN_B -1
#endif

#ifndef ENCODER_TWO_MODE
#define ENCODER_TWO_MODE ENCODER_MODE_NONE
#endif

#ifndef ENCODER_TWO_WRAP
#define ENCODER_TWO_WRAP 0
#endif

#ifndef ENCODER_TWO_MULTIPLIER
#define ENCODER_TWO_MULTIPLIER 1
#endif

#define MAX_ENCODERS 2
#define ENCODER_RADIUS 1440 // 4 phases * 360
#define ENCODER_PRECISION 16

// RotaryEncoderName Module Name
#define RotaryEncoderName "Rotary"

class RotaryEncoderInput : public GPAddon {
public:
virtual bool available();
virtual void setup(); // Rotary Setup
virtual void preprocess() {}
virtual void process(); // Rotary process
virtual std::string name() { return RotaryEncoderName; }

typedef struct {
bool enabled = false;
int8_t pinA = -1;
int8_t pinB = -1;
// encoder properties
uint16_t pulsesPerRevolution = 24;
RotaryEncoderPinMode mode = ENCODER_MODE_NONE;
int32_t minRange = -1;
int32_t maxRange = -1;
uint32_t resetAfter = 0;
bool allowWrapAround = false;
double multiplier = 0;
} EncoderPinMap;

typedef struct {
bool pinA = false;
bool pinB = false;
bool prevA = false;
bool prevB = false;
uint32_t updateTime = 0;
uint32_t changeTime = 0;
uint8_t delay = 1;
} EncoderPinState;
private:
EncoderPinState encoderState[MAX_ENCODERS];
int32_t encoderValues[MAX_ENCODERS];
int32_t prevValues[MAX_ENCODERS];
EncoderPinMap encoderMap[MAX_ENCODERS] = {
{false, -1, -1, 24, ENCODER_MODE_NONE, -1, -1},
{false, -1, -1, 24, ENCODER_MODE_NONE, -1, -1},
};

int32_t map(int32_t x, int32_t in_min, int32_t in_max, int32_t out_min, int32_t out_max);
int32_t bounds(int32_t x, int32_t out_min, int32_t out_max);
uint16_t mapEncoderValueStick(int8_t index, int32_t encoderValue, uint16_t ppr);
uint16_t mapEncoderValueTrigger(int8_t index, int32_t encoderValue, uint16_t ppr);
int8_t mapEncoderValueDPad(int8_t index, int32_t encoderValue, uint16_t ppr);

bool dpadUp = false;
bool dpadDown = false;
bool dpadLeft = false;
bool dpadRight = false;
};

#endif // _ROTARYENCODER_H
20 changes: 20 additions & 0 deletions proto/config.proto
Original file line number Diff line number Diff line change
Expand Up @@ -704,6 +704,25 @@ message InputHistoryOptions
optional uint32 row = 4;
}

message RotaryPinOptions
{
optional bool enabled = 1;
optional int32 pinA = 2;
optional int32 pinB = 3;
optional RotaryEncoderPinMode mode = 4;
optional uint32 pulsesPerRevolution = 5;
optional uint32 resetAfter = 6;
optional bool allowWrapAround = 7;
optional float multiplier = 8;
}

message RotaryOptions
{
optional bool enabled = 1;
optional RotaryPinOptions encoderOne = 2;
optional RotaryPinOptions encoderTwo = 3;
}

message AddonOptions
{
optional BootselButtonOptions bootselButtonOptions = 1;
Expand All @@ -729,6 +748,7 @@ message AddonOptions
optional InputHistoryOptions inputHistoryOptions = 21;
optional XBOnePassthroughOptions xbonePassthroughOptions = 22;
optional AnalogADS1256Options analogADS1256Options = 23;
optional RotaryOptions rotaryOptions = 24;
}

message MigrationHistory
Expand Down
17 changes: 16 additions & 1 deletion proto/enums.proto
Original file line number Diff line number Diff line change
Expand Up @@ -317,4 +317,19 @@ enum GPShape_Type
GP_SHAPE_DIAMOND = 2;
GP_SHAPE_POLYGON = 3;
GP_SHAPE_ARC = 4;
};
};

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

ENCODER_MODE_NONE = 0;
ENCODER_MODE_LEFT_ANALOG_X = 1;
ENCODER_MODE_LEFT_ANALOG_Y = 2;
ENCODER_MODE_RIGHT_ANALOG_X = 3;
ENCODER_MODE_RIGHT_ANALOG_Y = 4;
ENCODER_MODE_LEFT_TRIGGER = 5;
ENCODER_MODE_RIGHT_TRIGGER = 6;
ENCODER_MODE_DPAD_X = 7;
ENCODER_MODE_DPAD_Y = 8;
};
Loading