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

Add forced circularity option and minor fix to analog.cpp #321

Merged
merged 6 commits into from
Jun 20, 2023
Merged
Show file tree
Hide file tree
Changes from 4 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
10 changes: 10 additions & 0 deletions headers/addons/analog.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@
#define ANALOG_ADC_VRY -1
#endif

#ifndef FORCED_CIRCULARITY_ENABLED
#define FORCED_CIRCULARITY_ENABLED 0
#endif

#ifndef DEFAULT_ANALOG_DEADZONE
#define DEFAULT_ANALOG_DEADZONE 5
#endif

// Analog Module Name
#define AnalogName "Analog"

Expand All @@ -32,6 +40,8 @@ class AnalogInput : public GPAddon {
private:
uint8_t analogAdcPinX;
uint8_t analogAdcPinY;
bool forced_circularity;
uint8_t analog_deadzone;
};

#endif // _Analog_H_
2 changes: 2 additions & 0 deletions proto/config.proto
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,8 @@ message AnalogOptions

optional int32 analogAdcPinX = 2;
optional int32 analogAdcPinY = 3;
optional bool forced_circularity = 4;
optional uint32 analog_deadzone = 5;
}

message TurboOptions
Expand Down
29 changes: 24 additions & 5 deletions src/addons/analog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@

#include "hardware/adc.h"

#include <math.h>

#define ADC_MAX ((1 << 12) - 1)
#define ANALOG_CENTER 0.5f // 0.5f is center
#define ANALOG_DEADZONE 0.05f // move to config (future release)

bool AnalogInput::available() {
return Storage::getInstance().getAddonOptions().analogOptions.enabled;
Expand All @@ -17,6 +18,8 @@ void AnalogInput::setup() {
const AnalogOptions& options = Storage::getInstance().getAddonOptions().analogOptions;
analogAdcPinX = options.analogAdcPinX;
analogAdcPinY = options.analogAdcPinY;
forced_circularity = options.forced_circularity;
analog_deadzone = options.analog_deadzone;

// Make sure GPIO is high-impedance, no pullups etc
if ( isValidPin(analogAdcPinX) )
Expand All @@ -30,18 +33,34 @@ void AnalogInput::process()
Gamepad * gamepad = Storage::getInstance().GetGamepad();
float adc_x = ANALOG_CENTER;
float adc_y = ANALOG_CENTER;
float deadzone = analog_deadzone / 200.0f;

if ( isValidPin(analogAdcPinX) ) {
adc_select_input(analogAdcPinX-26); // ANALOG-X
adc_x = ((float)adc_read())/ADC_MAX;

if ( abs(adc_x - ANALOG_CENTER) < deadzone ) // deadzones
adc_x = ANALOG_CENTER;
}
if ( isValidPin(analogAdcPinY) ) {
adc_select_input(analogAdcPinY-26); // ANALOG-Y
adc_y = ((float)adc_read())/ADC_MAX;

if ( abs(adc_y - ANALOG_CENTER) < deadzone ) // deadzones
adc_y = ANALOG_CENTER;
}

// Alter coordinates to force perfect circularity
if (forced_circularity){
float adc_x_magnitude = adc_x-(ANALOG_CENTER);
float adc_y_magnitude = adc_y-(ANALOG_CENTER);
float adc_magnitude = sqrt((adc_x_magnitude * adc_x_magnitude) + (adc_y_magnitude * adc_y_magnitude));

if ( adc_magnitude > ANALOG_CENTER) {
adc_x = ((adc_x_magnitude / adc_magnitude) * ANALOG_CENTER + ANALOG_CENTER);
adc_y = ((adc_y_magnitude / adc_magnitude) * ANALOG_CENTER + ANALOG_CENTER);
}
}
if ( abs(adc_x - ANALOG_CENTER) < ANALOG_DEADZONE ) // deadzones
adc_x = ANALOG_CENTER;
if ( abs(adc_y - ANALOG_CENTER) < ANALOG_DEADZONE ) // deadzones
adc_y = ANALOG_CENTER;

// Convert to 16-bit value
gamepad->state.lx = (uint16_t)(65535.0f*adc_x);
Expand Down
4 changes: 4 additions & 0 deletions src/config_legacy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,8 @@ namespace ConfigLegacy
OnBoardLedMode onBoardLedMode;
uint8_t analogAdcPinX;
uint8_t analogAdcPinY;
uint8_t forced_circularity;
uint8_t analog_deadzone;
uint16_t bootselButtonMap;
uint8_t extraButtonPin;
uint32_t extraButtonMap;
Expand Down Expand Up @@ -929,6 +931,8 @@ bool ConfigUtils::fromLegacyStorage(Config& config)
SET_PROPERTY(analogOptions, enabled, legacyAddonOptions.AnalogInputEnabled);
SET_PROPERTY(analogOptions, analogAdcPinX, bytePinToIntPin(legacyAddonOptions.analogAdcPinX));
SET_PROPERTY(analogOptions, analogAdcPinY, bytePinToIntPin(legacyAddonOptions.analogAdcPinY));
SET_PROPERTY(analogOptions, forced_circularity, bytePinToIntPin(legacyAddonOptions.forced_circularity));
SET_PROPERTY(analogOptions, analog_deadzone, legacyAddonOptions.analog_deadzone);

BootselButtonOptions& bootselButtonOptions = config.addonOptions.bootselButtonOptions;
config.addonOptions.has_bootselButtonOptions = true;
Expand Down
2 changes: 2 additions & 0 deletions src/config_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,8 @@ void ConfigUtils::initUnsetPropertiesWithDefaults(Config& config)
INIT_UNSET_PROPERTY(config.addonOptions.analogOptions, enabled, !!ANALOG_INPUT_ENABLED);
INIT_UNSET_PROPERTY(config.addonOptions.analogOptions, analogAdcPinX, ANALOG_ADC_VRX);
INIT_UNSET_PROPERTY(config.addonOptions.analogOptions, analogAdcPinY, ANALOG_ADC_VRY);
INIT_UNSET_PROPERTY(config.addonOptions.analogOptions, enabled, !!FORCED_CIRCULARITY_ENABLED);
INIT_UNSET_PROPERTY(config.addonOptions.analogOptions, analog_deadzone, DEFAULT_ANALOG_DEADZONE);

// addonOptions.turboOptions
INIT_UNSET_PROPERTY(config.addonOptions.turboOptions, enabled, !!TURBO_ENABLED);
Expand Down
4 changes: 4 additions & 0 deletions src/configs/webconfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -844,6 +844,8 @@ std::string setAddonOptions()
AnalogOptions& analogOptions = Storage::getInstance().getAddonOptions().analogOptions;
docToPin(analogOptions.analogAdcPinX, doc, "analogAdcPinX");
docToPin(analogOptions.analogAdcPinY, doc, "analogAdcPinY");
docToValue(analogOptions.forced_circularity, doc, "forced_circularity");
docToValue(analogOptions.analog_deadzone, doc, "analog_deadzone");
docToValue(analogOptions.enabled, doc, "AnalogInputEnabled");

BootselButtonOptions& bootselButtonOptions = Storage::getInstance().getAddonOptions().bootselButtonOptions;
Expand Down Expand Up @@ -1053,6 +1055,8 @@ std::string getAddonOptions()
const AnalogOptions& analogOptions = Storage::getInstance().getAddonOptions().analogOptions;
writeDoc(doc, "analogAdcPinX", cleanPin(analogOptions.analogAdcPinX));
writeDoc(doc, "analogAdcPinY", cleanPin(analogOptions.analogAdcPinY));
writeDoc(doc, "forced_circularity", analogOptions.forced_circularity);
writeDoc(doc, "analog_deadzone", analogOptions.analog_deadzone);
writeDoc(doc, "AnalogInputEnabled", analogOptions.enabled);

const BootselButtonOptions& bootselButtonOptions = Storage::getInstance().getAddonOptions().bootselButtonOptions;
Expand Down
2 changes: 2 additions & 0 deletions www/server/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,8 @@ app.get("/api/getAddonsOptions", (req, res) => {
dualDirCombineMode: 0,
analogAdcPinX: -1,
analogAdcPinY: -1,
forced_circularity: 0,
analog_deadzone: 5,
bootselButtonMap: 0,
buzzerPin: -1,
buzzerVolume: 100,
Expand Down
31 changes: 30 additions & 1 deletion www/src/Pages/AddonsConfigPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,8 @@ const schema = yup.object().shape({
AnalogInputEnabled: yup.number().required().label('Analog Input Enabled'),
analogAdcPinX: yup.number().label('Analog Stick Pin X').validatePinWhenValue('AnalogInputEnabled'),
analogAdcPinY: yup.number().label('Analog Stick Pin Y').validatePinWhenValue('AnalogInputEnabled'),
forced_circularity: yup.number().label('Force Circularity').validateRangeWhenValue('AnalogInputEnabled', 0, 1),
analog_deadzone: yup.number().label('Deadzone Size (%)').validateRangeWhenValue('AnalogInputEnabled', 0, 100),

BoardLedAddonEnabled: yup.number().required().label('Board LED Add-On Enabled'),
onBoardLedMode: yup.number().label('On-Board LED Mode').validateSelectionWhenValue('BoardLedAddonEnabled', ON_BOARD_LED_MODES),
Expand Down Expand Up @@ -357,6 +359,8 @@ const defaultValues = {
dualDirCombineMode: 0,
analogAdcPinX : -1,
analogAdcPinY : -1,
forced_circularity : 0,
analog_deadzone: 5,
bootselButtonMap: 0,
buzzerPin: -1,
buzzerVolume: 100,
Expand Down Expand Up @@ -478,6 +482,10 @@ const sanitizeData = (values) => {
values.analogAdcPinX = parseInt(values.analogAdcPinX);
if (!!values.analogAdcPinY)
values.analogAdcPinY = parseInt(values.analogAdcPinY);
if (!!values.forced_circularity)
values.forced_circularity = parseInt(values.forced_circularity);
if (!!values.analog_deadzone)
values.analog_deadzone = parseInt(values.analog_deadzone);
if (!!values.bootselButtonMap)
values.bootselButtonMap = parseInt(values.bootselButtonMap);
if (!!values.buzzerPin)
Expand Down Expand Up @@ -718,6 +726,27 @@ export default function AddonsConfigPage() {
>
{ANALOG_PIN_OPTIONS}
</FormSelect>
<FormCheck
label="Force Circularity"
type="switch"
id="Forced_circularity"
className="col-sm-3 ms-2"
isInvalid={false}
checked={Boolean(values.forced_circularity)}
onChange={(e) => {handleCheckbox("forced_circularity", values); handleChange(e);}}
/>
<FormControl type="number"
label="Deadzone Size (%)"
name="analog_deadzone"
className="form-control-sm"
groupClassName="col-sm-3 mb-3"
value={values.analog_deadzone}
error={errors.analog_deadzone}
isInvalid={errors.analog_deadzone}
onChange={handleChange}
min={0}
max={100}
/>
</Row>
</div>
<FormCheck
Expand Down Expand Up @@ -768,7 +797,7 @@ export default function AddonsConfigPage() {
error={errors.turboShotCount}
isInvalid={errors.turboShotCount}
onChange={handleChange}
min={2}
min={5}
max={30}
/>
<FormSelect
Expand Down