Skip to content
Open
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
4 changes: 3 additions & 1 deletion headers/addons/analog.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@ typedef struct
float out_deadzone;
bool auto_calibration;
bool forced_circularity;
uint32_t joystick_center_x;
uint32_t joystick_center_y;
} adc_instance;

class AnalogInput : public GPAddon {
Expand All @@ -148,4 +150,4 @@ class AnalogInput : public GPAddon {
adc_instance adc_pairs[ADC_COUNT];
};

#endif // _Analog_H_
#endif // _Analog_H_
4 changes: 4 additions & 0 deletions proto/config.proto
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,10 @@ message AnalogOptions
optional uint32 outer_deadzone2 = 21;
optional bool auto_calibrate2 = 22;
optional bool forced_circularity2 = 23;
optional uint32 joystick_center_x = 24;
optional uint32 joystick_center_y = 25;
optional uint32 joystick_center_x2 = 26;
optional uint32 joystick_center_y2 = 27;
}

message TurboOptions
Expand Down
16 changes: 14 additions & 2 deletions src/addons/analog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ void AnalogInput::setup() {
adc_pairs[0].out_deadzone = analogOptions.outer_deadzone / 100.0f;
adc_pairs[0].auto_calibration = analogOptions.auto_calibrate;
adc_pairs[0].forced_circularity = analogOptions.forced_circularity;
adc_pairs[0].joystick_center_x = analogOptions.joystick_center_x;
adc_pairs[0].joystick_center_y = analogOptions.joystick_center_y;
adc_pairs[1].x_pin = analogOptions.analogAdc2PinX;
adc_pairs[1].y_pin = analogOptions.analogAdc2PinY;
adc_pairs[1].analog_invert = analogOptions.analogAdc2Invert;
Expand All @@ -44,6 +46,8 @@ void AnalogInput::setup() {
adc_pairs[1].out_deadzone = analogOptions.outer_deadzone2 / 100.0f;
adc_pairs[1].auto_calibration = analogOptions.auto_calibrate2;
adc_pairs[1].forced_circularity = analogOptions.forced_circularity2;
adc_pairs[1].joystick_center_x = analogOptions.joystick_center_x2;
adc_pairs[1].joystick_center_y = analogOptions.joystick_center_y2;


// Setup defaults and helpers
Expand All @@ -66,13 +70,19 @@ void AnalogInput::setup() {
if (adc_pairs[i].auto_calibration) {
adc_select_input(adc_pairs[i].x_pin - ADC_PIN_OFFSET);
adc_pairs[i].x_center = adc_read();
} else {
// if auto calibration is disabled, attempt to use stored manual calibration value
adc_pairs[i].x_center = adc_pairs[i].joystick_center_x;
}
}
if(isValidPin(adc_pairs[i].y_pin)) {
adc_gpio_init(adc_pairs[i].y_pin);
if (adc_pairs[i].auto_calibration) {
adc_select_input(adc_pairs[i].y_pin - ADC_PIN_OFFSET);
adc_pairs[i].y_center = adc_read();
} else {
// if auto calibration is disabled, attempt to use stored manual calibration value
adc_pairs[i].y_center = adc_pairs[i].joystick_center_y;
}
}
}
Expand Down Expand Up @@ -139,7 +149,9 @@ void AnalogInput::process() {
float AnalogInput::readPin(int stick_num, Pin_t pin_adc, uint16_t center) {
adc_select_input(pin_adc);
uint16_t adc_value = adc_read();
if (adc_pairs[stick_num].auto_calibration) {
// Apply calibration only if auto calibration is enabled or manual calibration has been performed
// Manual calibration is considered performed if the center value is not 0 (default)
if (adc_pairs[stick_num].auto_calibration || center != 0) {
if (adc_value > center) {
adc_value = map(adc_value, center, ADC_MAX, ADC_MAX / 2, ADC_MAX);
} else if (adc_value == center) {
Expand Down Expand Up @@ -174,4 +186,4 @@ void AnalogInput::radialDeadzone(int stick_num, adc_instance & adc_inst) {
adc_inst.y_value = ((adc_inst.y_magnitude / adc_inst.xy_magnitude) * scaling_factor) + ANALOG_CENTER;
adc_inst.x_value = std::clamp(adc_inst.x_value, ANALOG_MINIMUM, ANALOG_MAX);
adc_inst.y_value = std::clamp(adc_inst.y_value, ANALOG_MINIMUM, ANALOG_MAX);
}
}
100 changes: 100 additions & 0 deletions src/webconfig.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include "config.pb.h"
#include "base64.h"
#include "hardware/adc.h"
#include "helper.h"

#include "drivermanager.h"
#include "storagemanager.h"
Expand Down Expand Up @@ -1684,6 +1686,10 @@ std::string setAddonOptions()
docToValue(analogOptions.outer_deadzone2, doc, "outer_deadzone2");
docToValue(analogOptions.auto_calibrate, doc, "auto_calibrate");
docToValue(analogOptions.auto_calibrate2, doc, "auto_calibrate2");
docToValue(analogOptions.joystick_center_x, doc, "joystickCenterX");
docToValue(analogOptions.joystick_center_y, doc, "joystickCenterY");
docToValue(analogOptions.joystick_center_x2, doc, "joystickCenterX2");
docToValue(analogOptions.joystick_center_y2, doc, "joystickCenterY2");
docToValue(analogOptions.analog_smoothing, doc, "analog_smoothing");
docToValue(analogOptions.analog_smoothing2, doc, "analog_smoothing2");
docToValue(analogOptions.smoothing_factor, doc, "smoothing_factor");
Expand Down Expand Up @@ -2138,6 +2144,10 @@ std::string getAddonOptions()
writeDoc(doc, "outer_deadzone2", analogOptions.outer_deadzone2);
writeDoc(doc, "auto_calibrate", analogOptions.auto_calibrate);
writeDoc(doc, "auto_calibrate2", analogOptions.auto_calibrate2);
writeDoc(doc, "joystickCenterX", analogOptions.joystick_center_x);
writeDoc(doc, "joystickCenterY", analogOptions.joystick_center_y);
writeDoc(doc, "joystickCenterX2", analogOptions.joystick_center_x2);
writeDoc(doc, "joystickCenterY2", analogOptions.joystick_center_y2);
writeDoc(doc, "analog_smoothing", analogOptions.analog_smoothing);
writeDoc(doc, "analog_smoothing2", analogOptions.analog_smoothing2);
writeDoc(doc, "smoothing_factor", analogOptions.smoothing_factor);
Expand Down Expand Up @@ -2569,6 +2579,94 @@ std::string reboot() {
return serialize_json(doc);
}

// NEW API: return current raw ADC reading for the configured analog pins
std:: string getJoystickCenter() {
const size_t capacity = JSON_OBJECT_SIZE(10);
DynamicJsonDocument doc(capacity);
const AnalogOptions& analogOptions = Storage::getInstance().getAddonOptions().analogOptions;

uint16_t x = 0, y = 0;
bool success = true;
std::string error_msg = "";

// Check if analog input is enabled
if (!analogOptions.enabled) {
success = false;
error_msg = "Analog input is not enabled";
} else {
// Initialize ADC if not already initialized
adc_init();

// Check if specific stick is requested via query parameter
// For now, we'll read both sticks and return the appropriate one
// In a more sophisticated implementation, we could parse query parameters

// Read first stick X/Y
if (isValidPin(analogOptions.analogAdc1PinX)) {
adc_gpio_init(analogOptions.analogAdc1PinX);
adc_select_input(analogOptions.analogAdc1PinX - 26);
x = adc_read();
}
if (isValidPin(analogOptions.analogAdc1PinY)) {
adc_gpio_init(analogOptions.analogAdc1PinY);
adc_select_input(analogOptions.analogAdc1PinY - 26);
y = adc_read();
}
}

JsonObject o = doc.to<JsonObject>();
o["success"] = success;
if (!success) {
o["error"] = error_msg;
} else {
o["x"] = x;
o["y"] = y;
}
return serialize_json(doc);
}

// NEW API: return current raw ADC reading for stick 2
std:: string getJoystickCenter2() {
const size_t capacity = JSON_OBJECT_SIZE(10);
DynamicJsonDocument doc(capacity);
const AnalogOptions& analogOptions = Storage::getInstance().getAddonOptions().analogOptions;

uint16_t x = 0, y = 0;
bool success = true;
std::string error_msg = "";

// Check if analog input is enabled
if (!analogOptions.enabled) {
success = false;
error_msg = "Analog input is not enabled";
} else {
// Initialize ADC if not already initialized
adc_init();

// Read second stick X/Y
if (isValidPin(analogOptions.analogAdc2PinX)) {
adc_gpio_init(analogOptions.analogAdc2PinX);
adc_select_input(analogOptions.analogAdc2PinX - 26);
x = adc_read();
}
if (isValidPin(analogOptions.analogAdc2PinY)) {
adc_gpio_init(analogOptions.analogAdc2PinY);
adc_select_input(analogOptions.analogAdc2PinY - 26);
y = adc_read();
}
}

JsonObject o = doc.to<JsonObject>();
o["success"] = success;
if (!success) {
o["error"] = error_msg;
} else {
o["x"] = x;
o["y"] = y;
}
return serialize_json(doc);
}

typedef std::string (*HandlerFuncPtr)();
static const std::pair<const char*, HandlerFuncPtr> handlerFuncs[] =
{
Expand Down Expand Up @@ -2617,6 +2715,8 @@ static const std::pair<const char*, HandlerFuncPtr> handlerFuncs[] =
{ "/api/abortGetHeldPins", abortGetHeldPins },
{ "/api/getUsedPins", getUsedPins },
{ "/api/getConfig", getConfig },
{ "/api/getJoystickCenter", getJoystickCenter },
{ "/api/getJoystickCenter2", getJoystickCenter2 },
#if !defined(NDEBUG)
{ "/api/echo", echo },
#endif
Expand Down
Loading