Skip to content

Conversation

@wongfei2009
Copy link

Summary

This PR adds hardware-based turbo controls to GP2040-CE using an MCP23017 I2C GPIO expander. This enables users to add physical toggle switches for per-button turbo control and an optional analog speed dial, without requiring boards with many spare GPIO pins.

Key Features

  • 8 physical toggle switches for per-button turbo control (B1-B4, L1-L2, R1-R2)
  • Analog speed dial (potentiometer) for adjustable turbo rate (2-30 shots/second)
  • I2C bus sharing with display - no additional pins required beyond I2C SDA/SCL
  • Real-time web diagnostics showing switch states and speed dial position
  • Graceful fallback - feature is optional and doesn't affect boards without hardware

Hardware Requirements

  • MCP23017 I2C GPIO Expander breakout board (~$1-2)
  • 8× SPST toggle switches (or DIP-8 switch array)
  • 10kΩ linear potentiometer (optional, for speed dial)

Implementation Details

New Components:

  • lib/mcp23017/ - Generic MCP23017 driver library
    • Simple API for reading GPIO pins via I2C
    • Configurable I2C address (default 0x20)
    • Built-in pull-up resistor support

Modified Components:

  • src/addons/turbo.cpp - Enhanced turbo addon to read I2C switches
  • src/addons/display.cpp - Added I2C device scanning diagnostics
  • src/webconfig.cpp - New /api/getTurboDiagnostics endpoint
  • www/src/Addons/Turbo.tsx - Real-time switch state display

Configuration:

  • Feature is opt-in via TURBO_I2C_SWITCHES_ENABLED in BoardConfig.h
  • Currently enabled for Pico board config as reference implementation
  • Can be easily adapted to any board with I2C bus

Board Compatibility

This feature is designed to work with any RP2040-based board that has:

  • An I2C bus (shared with display or dedicated)
  • Optional: One ADC pin for speed dial

The reference implementation uses the Pico board configuration.

Web Configurator Integration

The turbo configuration page now displays real-time diagnostics:

  • Live switch states for all 8 buttons (ON/OFF badges)
  • Speed dial position (percentage and raw ADC value)
  • I2C device detection status
  • Auto-refresh every 500ms

Testing

  • ✅ Builds successfully on macOS with Pico SDK 2.1.1
  • ✅ MCP23017 driver tested with I2C communication
  • ✅ Web configurator displays real-time switch states
  • ✅ No conflicts with display on shared I2C bus
  • ✅ Graceful fallback when MCP23017 not detected
  • ✅ Hardware tested on physical device - all switches and speed dial working correctly

Documentation

In-repo documentation added:

  • configs/Pico/README.md - Hardware setup, pin assignments, switch mapping
  • configs/Pico/BoardConfig.h - Detailed inline configuration comments
  • lib/mcp23017/mcp23017.h - Doxygen-style API documentation
  • src/addons/turbo.cpp - Implementation comments
  • www/server/docs/GP2040-CE.postman_collection.json - API endpoint documentation

External documentation needed:

  • Wiring diagrams for MCP23017 connection
  • Troubleshooting guide for I2C issues
  • Complete setup tutorial

Switch Mapping

MCP23017 Port A pins map to buttons as follows:

  • GPA0 → B1 (Face button 1)
  • GPA1 → B2 (Face button 2)
  • GPA2 → B3 (Face button 3)
  • GPA3 → B4 (Face button 4)
  • GPA4 → L1 (Left shoulder 1)
  • GPA5 → R1 (Right shoulder 1)
  • GPA6 → L2 (Left shoulder 2)
  • GPA7 → R2 (Right shoulder 2)

Switches are wired active-low (closed = turbo enabled).

Configuration Example

// In BoardConfig.h
#define TURBO_I2C_SWITCHES_ENABLED 1
#define TURBO_I2C_SDA_PIN 0
#define TURBO_I2C_SCL_PIN 1
#define TURBO_I2C_BLOCK i2c0
#define TURBO_I2C_SPEED 400000
#define TURBO_I2C_ADDR 0x20

// Optional speed dial
#define PIN_SHMUP_DIAL 26

Future Enhancements

Possible improvements for future PRs:

  • Additional board configurations
  • Web UI for MCP23017 address scanning
  • Support for MCP23008 (8-pin variant)
  • Interrupt-based switch reading for lower latency

Checklist

  • Code builds successfully
  • Feature is opt-in and doesn't break existing configurations
  • Documentation added (README, inline comments, API docs)
  • Web configurator integration complete
  • Graceful error handling implemented
  • Hardware tested on physical device
  • External documentation (wiring diagrams, setup guide)

🤖 Generated with Claude Code

Co-Authored-By: Claude noreply@anthropic.com

wongfei2009 and others added 7 commits December 24, 2025 22:17
…rify goals, hardware requirements, and implementation details for broader compatibility.
Enhanced documentation across multiple files to prepare for upstream PR:

- configs/Pico/README.md: Added Hardware Turbo Controls section with pin
  assignments, required hardware list, switch mapping, and configuration

- configs/Pico/BoardConfig.h: Added detailed inline comments explaining
  MCP23017 requirements, I2C bus sharing, active-low wiring, and all
  configuration parameters

- lib/mcp23017/mcp23017.h: Added doxygen-style documentation for the
  MCP23017 driver library with hardware specs and API descriptions

- src/addons/turbo.cpp: Enhanced code comments for I2C initialization
  and switch reading logic with detailed explanations

- www/server/docs/GP2040-CE.postman_collection.json: Added API
  documentation for /api/getTurboDiagnostics endpoint

All documentation follows GP2040-CE conventions. Build verified successful.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
All hardware and software implementation phases have been successfully completed:
- Phase 1: MCP23017 Library ✅
- Phase 2: Hardware Assembly ✅
- Phase 3: Turbo Addon Integration ✅
- Phase 4: Testing & Validation ✅

Added comprehensive project status sections:
- Project completion summary
- Technical achievements and key files
- Testing results (all PASS)
- Future enhancement suggestions
- Upstream contribution checklist

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@mikepparks
Copy link
Contributor

Currently, this is set up to add functionality that would be optional to the build process, rather than as an addon that could benefit all builds. If we're to add another IO expansion driver, it needs to be available to all devices. A few things that I would request if we were to consider this for merging.

  • Decouple this functionality from the Turbo addon into its own IO expander addon, such as the PCF8575 addon. There is much to be gained from having another IO expansion driver addon, so requiring it to be for Turbo functionality only is a bit limiting. We have an Event system that can be set up to handle any necessary on-the-fly option changes you might want to make.
  • The scani2c is a nice addition, but we already have a getI2CPeripheralMap that does the same thing. The changes here to the Display configuration functionality are a nice addition, however, and could be broken out to their own separate PR as it feels slightly out of scope here.
  • getTurboDiagnostics could benefit from using the peripheral driver's scan functionality rather than hard-coding the addresses in webconfig.cpp.

There is also the topic of AI assisted development here. We typically do not approve PRs that have been developed using AI tools as the code cannot be guaranteed functional. Even if my requests can be addressed, this will require further discussion with the team before we can consider merging it in, and we will need to obtain the necessary hardware to be able to vet it further.

@wongfei2009
Copy link
Author

Thank you for the detailed feedback. I am happy enough to keep this feature in my own fork.

This feature is mainly for people who want to mod their old-school arcade stick with the great GP2040-CE project. These old-school sticks such as SEGA HSS-0136 have hardware turbo on-off switches and turbo speed slider. It will be interesting to be able to retain them.

I think GP2040-CE is a wonderful project. So, I try to contribute this PR so that other retro game fans can mod their HSS-0136 without giving up those buttons.

Lastly, on AI asisted development, I think the PR should be considered based on the quality of the PR, rather than whether AI tool has been used or not. PR without using AI tools cannot be guaranteed functional as well. But I fully understand the concern from the maintainer, that will create a lot of review burden if someone just use AI tools to produce a lot of low-quality PRs without verifications. That's why I intentionally disclose this feature has been developed using AI tools. I did review the codes and test the feature working properly on my hardware.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants