convert files from CRLF endings to LF endings (#332)

bss@garnet ~/proj/GP2040-CE % find . -type f -exec file {} \; | grep CRLF | cut -d ':' -f 1 | xargs dos2unix
dos2unix: converting file ./lib/TinyUSB_Gamepad/src/ps4_driver.h to Unix format...
dos2unix: converting file ./lib/TinyUSB_Gamepad/src/ps4_driver.cpp to Unix format...
dos2unix: converting file ./lib/NeoPico/src/generated/ws2812.pio.h to Unix format...
dos2unix: converting file ./lib/httpd/fsdata.c to Unix format...
dos2unix: converting file ./www/.eslintrc.yml to Unix format...
dos2unix: converting file ./www/index.html to Unix format...
dos2unix: converting file ./www/vite.config.ts to Unix format...
dos2unix: converting file ./www/src/Components/ColorScheme.jsx to Unix format...
dos2unix: converting file ./www/src/index.jsx to Unix format...
dos2unix: converting file ./www/src/Icons/MoonStars.tsx to Unix format...
dos2unix: converting file ./www/src/Icons/CircleHalf.tsx to Unix format...
dos2unix: converting file ./www/src/Icons/Sun.tsx to Unix format...
dos2unix: converting file ./www/server/app.js to Unix format...
dos2unix: converting file ./www/.env to Unix format...
dos2unix: converting file ./src/addons/ps4mode.cpp to Unix format...
dos2unix: converting file ./.github/workflows/cmake.yml to Unix format...
dos2unix: converting file ./headers/gamepad/descriptors/PS4Descriptors.h to Unix format...
dos2unix: converting file ./headers/addons/ps4mode.h to Unix format...
dos2unix: converting file ./headers/mbedtls_config.h to Unix format...
dos2unix: converting file ./headers/configs/base64.h to Unix format...
dos2unix: converting file ./configs/Stress/README.md to Unix format...
dos2unix: converting file ./configs/Stress/env.ini to Unix format...
dos2unix: converting file ./configs/Stress/stress.h to Unix format...
dos2unix: converting file ./configs/Stress/BoardConfig.h to Unix format...
This commit is contained in:
Brian S. Stephan
2023-06-14 09:19:20 -05:00
committed by GitHub
parent fb753f63fd
commit 70b1a9f1bd
24 changed files with 1938 additions and 1937 deletions

1
.gitattributes vendored Normal file
View File

@@ -0,0 +1 @@
* text=auto

View File

@@ -1,60 +1,60 @@
name: CMake
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
pull_request_target:
branches: [ "main" ]
workflow_dispatch:
env:
BUILD_TYPE: Release
jobs:
call-node-workflow:
uses: ./.github/workflows/node.js.yml
build:
needs: call-node-workflow
# The CMake configure and build commands are platform agnostic and should work equally well on Windows or Mac.
# You can convert this to a matrix build if you need cross-platform coverage.
# See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix
runs-on: ubuntu-latest
strategy:
matrix:
GP2040_BOARDCONFIG: [Pico, BentoBox, DURAL, FightboardV3, FightboardV3Mirrored, FlatboxRev4, FlatboxRev5, KB2040, MavercadeKeebfighter, PicoAnn, PicoFightingBoard, ReflexEncoder, RP2040AdvancedBreakoutBoard, RP2040MiniBreakoutBoard, SparkFunProMicro, WaveshareZero, Stress ]
steps:
#Global Setup
- name: Checkout GP2040-CE
uses: actions/checkout@v3
- name: Setup SDK pipeline
uses: Fortinbra/RaspberryPiPicoBuild@v1
- name: Download a Build Artifact
uses: actions/download-artifact@v3.0.2
with:
name: fsData
path: ${{github.workspace}}/lib/httpd/
- name: Get core count
id: core_count
run : cat /proc/cpuinfo | grep processor | wc -l
#End Global Setup
- name: Pico Build Configure CMake
shell: bash
run: PICO_SDK_PATH=${{github.workspace}}/pico-sdk GP2040_BOARDCONFIG=${{ matrix.GP2040_BOARDCONFIG }} SKIP_WEBBUILD=TRUE cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}
- name: Pico Build
shell: bash
run: GP2040_BOARDCONFIG=${{ matrix.GP2040_BOARDCONFIG }} cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} --parallel ${{steps.core_count.outputs.output}}
- name: Upload Pico Artifact
uses: actions/upload-artifact@v3.1.1
with:
name: GP2040-CE - ${{ matrix.GP2040_BOARDCONFIG }}
path: ${{github.workspace}}/build/GP2040-CE_*_${{ matrix.GP2040_BOARDCONFIG }}.uf2
if-no-files-found: error
name: CMake
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
pull_request_target:
branches: [ "main" ]
workflow_dispatch:
env:
BUILD_TYPE: Release
jobs:
call-node-workflow:
uses: ./.github/workflows/node.js.yml
build:
needs: call-node-workflow
# The CMake configure and build commands are platform agnostic and should work equally well on Windows or Mac.
# You can convert this to a matrix build if you need cross-platform coverage.
# See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix
runs-on: ubuntu-latest
strategy:
matrix:
GP2040_BOARDCONFIG: [Pico, BentoBox, DURAL, FightboardV3, FightboardV3Mirrored, FlatboxRev4, FlatboxRev5, KB2040, MavercadeKeebfighter, PicoAnn, PicoFightingBoard, ReflexEncoder, RP2040AdvancedBreakoutBoard, RP2040MiniBreakoutBoard, SparkFunProMicro, WaveshareZero, Stress ]
steps:
#Global Setup
- name: Checkout GP2040-CE
uses: actions/checkout@v3
- name: Setup SDK pipeline
uses: Fortinbra/RaspberryPiPicoBuild@v1
- name: Download a Build Artifact
uses: actions/download-artifact@v3.0.2
with:
name: fsData
path: ${{github.workspace}}/lib/httpd/
- name: Get core count
id: core_count
run : cat /proc/cpuinfo | grep processor | wc -l
#End Global Setup
- name: Pico Build Configure CMake
shell: bash
run: PICO_SDK_PATH=${{github.workspace}}/pico-sdk GP2040_BOARDCONFIG=${{ matrix.GP2040_BOARDCONFIG }} SKIP_WEBBUILD=TRUE cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}
- name: Pico Build
shell: bash
run: GP2040_BOARDCONFIG=${{ matrix.GP2040_BOARDCONFIG }} cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} --parallel ${{steps.core_count.outputs.output}}
- name: Upload Pico Artifact
uses: actions/upload-artifact@v3.1.1
with:
name: GP2040-CE - ${{ matrix.GP2040_BOARDCONFIG }}
path: ${{github.workspace}}/build/GP2040-CE_*_${{ matrix.GP2040_BOARDCONFIG }}.uf2
if-no-files-found: error

View File

@@ -1,265 +1,265 @@
/*
* SPDX-License-Identifier: MIT
* SPDX-FileCopyrightText: Copyright (c) 2021 Jason Skuby (mytechtoybox.com)
*/
#ifndef PICO_BOARD_CONFIG_H_
#define PICO_BOARD_CONFIG_H_
#include <GamepadEnums.h>
// This is the main pin definition section.
// This will let you specify which GPIO pin each button is assigned too.
// You can set any of the main pins as `-1` to disable it.
// The Turbo pin and LS + RS slider pins can also be set to `-1` to disable that functionality.
// Please note that only when `PIN_BUTTON_TURBO` is set to `-1` will the `T##` be removed from a connected display.
// Please note that only when `PIN_SLIDER_LS` and `PIN_SLIDER_RS` are set to `-1` will the button combo shortcut for DP/LS/RS work.
// The buttons are listed in GP2040 configuration, beside each the listed order is *GP2040 / Xinput / Switch / PS3 / Directinput / Arcade*
#define PIN_DPAD_UP 26 // UP
#define PIN_DPAD_DOWN 28 // DOWN
#define PIN_DPAD_LEFT 29 // LEFT
#define PIN_DPAD_RIGHT 27 // RIGHT
#define PIN_BUTTON_B1 1 // B1 / A / B / Cross / 2 / K1
#define PIN_BUTTON_B2 3 // B2 / B / A / Circle / 3 / K2
#define PIN_BUTTON_B3 0 // B3 / X / Y / Square / 1 / P1
#define PIN_BUTTON_B4 2 // B4 / Y / X / Triangle / 4 / P2
#define PIN_BUTTON_L1 5 // L1 / LB / L / L1 / 5 / P4
#define PIN_BUTTON_R1 4 // R1 / RB / R / R1 / 6 / P3
#define PIN_BUTTON_L2 6 // L2 / LT / ZL / L2 / 7 / K4
#define PIN_BUTTON_R2 7 // R2 / RT / ZR / R2 / 8 / K3
#define PIN_BUTTON_S1 8 // S1 / Back / Minus / Select / 9 / Coin
#define PIN_BUTTON_S2 9 // S2 / Start / Plus / Start / 10 / Start
#define PIN_BUTTON_L3 12 // L3 / LS / LS / L3 / 11 / LS
#define PIN_BUTTON_R3 13 // R3 / RS / RS / R3 / 12 / RS
#define PIN_BUTTON_A1 14 // A1 / Guide / Home / PS / 13 / ~
#define PIN_BUTTON_A2 15 // A2 / ~ / Capture / ~ / 14 / ~
#define PIN_BUTTON_TURBO -1 // Turbo
#define PIN_BUTTON_REVERSE -1 // UDLR Reverse
#define PIN_SLIDER_LS -1 // Left Stick Slider
#define PIN_SLIDER_RS -1 // Right Stick Slider
#define PIN_SLIDER_SOCD_ONE -1 // SOCD Slider Pin One
#define PIN_SLIDER_SOCD_TWO -1 // SOCD Slider Pin Two
// This is the SOCD section.
// SOCD stands for `simultaneous opposing cardinal directions`.
// There are three options for `DEFAULT_SOCD_MODE` currently:
// 1 - `SOCD_MODE_NEUTRAL` - This is a neutral SOCD. EG. when you press `up` + `down` no input will be registered.
// 2 - `SOCD_MODE_UP_PRIORITY` - This is up priority SOCD. EG. when you press `up` + `down` `up` will be registered.
// 3 - `SOCD_MODE_SECOND_INPUT_PRIORITY` - This is last priority SOCD. EG. when you press and hold `up` then press `down` `down` will be registered.
// 4 - `SOCD_MODE_FIRST_INPUT_PRIORITY` - This is first priority SOCD. EG. when you press and hold `up` then press `down` `up` will be registered.
#define DEFAULT_SOCD_MODE SOCD_MODE_NEUTRAL
// SOCD Slider Slot Defaults
#define SLIDER_SOCD_SLOT_ONE SOCD_MODE_UP_PRIORITY
#define SLIDER_SOCD_SLOT_TWO SOCD_MODE_SECOND_INPUT_PRIORITY
#define SLIDER_SOCD_SLOT_DEFAULT SOCD_MODE_NEUTRAL
#define DEFAULT_FORCED_SETUP_MODE FORCED_SETUP_MODE_OFF // FORCED_SETUP_MODE_OFF, FORCED_SETUP_MODE_LOCK_MODE_SWITCH, FORCED_SETUP_MODE_LOCK_WEB_CONFIG, FORCED_SETUP_MODE_LOCK_BOTH
#define DEFAULT_LOCK_HOTKEYS false // or true
// This is the LEDs section.
// The default `TURBO_LED_PIN` pin is set to `15` ( it is recommended to run through 3V3(OUT) with a resistor)
// The Turbo LED will flash at a speed consistant with the set speed of the Turbo when a Turbo button is active.
// It is recommended to disable the `TURBO_LED_PIN` by setting it to `-1` if you are sensitive of flashing lights.
// The default `BOARD_LEDS_PIN` pin is set to `28`.
// The board LED pin will allow you to connect addressible RGB LEDs on the Pico.
// Addressible RGB LEDs should be connected to the `VBUS` pin (#40), an avalible ground pin and the defined `BOARD_LEDS_PIN`.
// Special note - You should only ever use addressible RGB LEDs that are rated for 5v operation on the Pico.
// The defualt `LED_BRIGHTNESS_MAXIMUM` value is `50`.
// This will change how bright the LEDs are with `0` being off and `100` being full brightness.
// The minimum `LED_BRIGHTNESS_MAXIMUM` value is `0`.
// The maximum `LED_BRIGHTNESS_MAXIMUM` value is `100`.
// The defualt `LED_BRIGHTNESS_STEPS` value is `5`.
// This will change how many brightness steps there are when increasing or decreasing the brightness of the LEDs via the onboard shortcut.
// It is recommend to keep this value at `5` or `10`.
// The defualt `LED_FORMAT` is `LED_FORMAT_GRB`.
// You can also choose the `LED_FORMAT` of `LED_FORMAT_RGB` if your addressible RGB LEDs are not working as intended.
// The defualt `LEDS_PER_PIXEL` is set to `1`.
// This will change how many addressible RGB LEDs there are per button.
// The default LEDS_[BUTTON] is an order and has nothing to do with what GPIO pin something is connected to.
// Unless you are planning on running custom animations I would recommmend you leave this as is.
#define TURBO_LED_PIN -1
#define BOARD_LEDS_PIN -1
#define LED_BRIGHTNESS_MAXIMUM 50
#define LED_BRIGHTNESS_STEPS 5
#define LED_FORMAT LED_FORMAT_GRB
#define LEDS_PER_PIXEL 1
#define LEDS_DPAD_LEFT 0
#define LEDS_DPAD_DOWN 1
#define LEDS_DPAD_RIGHT 2
#define LEDS_DPAD_UP 3
#define LEDS_BUTTON_B3 4
#define LEDS_BUTTON_B4 5
#define LEDS_BUTTON_R1 6
#define LEDS_BUTTON_L1 7
#define LEDS_BUTTON_B1 8
#define LEDS_BUTTON_B2 9
#define LEDS_BUTTON_R2 10
#define LEDS_BUTTON_L2 11
// This is the Player LED section.
// In this section you can specify if Player LEDs will be active, and, if active, which pins will be used for them.
// The defualt is `PLED_TYPE_NONE` which will turn the Player LEDs off.
// The default pin for each Player LED is `-1` which disables it.
// To enable a `PLED#_PIN`, replace the `-1` with the GPIO pin number that is desired.
// There are three options for `PLED_TYPE` currently:
// 1 - `PLED_TYPE_NONE` - This will disable the Player LEDs
// 2 - `PLED_TYPE_PWM` - This will enable the Player LEDs ( it is recommended to run through 3V3(OUT) with a resistor)
// 3 - `PLED_TYPE_RGB` - This will enable the Player LEDs as addressible RGB LEDs (please not that this has not been implemented yet)
#define PLED_TYPE PLED_TYPE_NONE
#define PLED1_PIN -1
#define PLED2_PIN -1
#define PLED3_PIN -1
#define PLED4_PIN -1
// This is the Analog section.
// In this section you can specify if Analog is enabled, and, if endabled, which pins will be used for it.
// The default for `ANALOG_ADC_VRX` and `ANALOG_ADC_VRY` is `-1` which disables them.
// To enable a `ANALOG_ADC_VRX` and `ANALOG_ADC_VRY`, replace the `-1` with the GPIO pin numbers that are desired.
#define ANALOG_ADC_VRX -1
#define ANALOG_ADC_VRY -1
// Reverse Button section
#define REVERSE_LED_PIN -1
// This is the I2C Display section (commonly known as the OLED display section).
// In this section you can specify if a display as been enabled, which pins are assined to it, the block address and speed.
// The default for `HAS_I2C_DISPLAY` is `1` which enables it.
// To disable the display you can change `HAS_I2C_DISPLAY` to `-1`.
// The default `I2C_SDA_PIN` is `0`.
// The defualt `I2C_SCL_PIN` is `1`.
// The defualt `I2C_BLOCK` is `12c0`.
// If you change the `I2C_SDA_PIN` and `I2C_SCL_PIN` pin mapping, you may need to change the `I2C_BLOCK` as well.
// The defualt `I2C_SPEED` is `400000`.
// This should be more than fast enough for most displays.
// Some smaller displays (like 0.96" and 1.31") can go up to `800000` or even `1000000`.
// The default `DISPLAY_FLIP` is `0`.
// This can be changed to `1` to have the dispaly output flipped.
// The default `DISPLAY_INVERY` is `0`.
// This can be changed to `1` to have the color on the display inverted.
// The default `BUTTON_LAYOUT` is `BUTTON_LAYOUT_STICK` which will show an arcade stick on the left hand side of the display.
// There are seven options for `BUTTON_LAYOUT` currently:
// 1 - BUTTON_LAYOUT_STICK - This is a basic joystick layout
// 2 - BUTTON_LAYOUT_STICKLESS - This is a basic stickless (all button) layout
// 3 - BUTTON_LAYOUT_BUTTONS_ANGLED - This a WASD button layout that is angled
// 4 - BUTTON_LAYOUT_BUTTONS_BASIC - This a WASD button layout that is straight
// 5 - BUTTON_LAYOUT_KEYBOARD_ANGLED - This is a WASD keyboard layout that is angled
// 6 - BUTTON_LAYOUT_KEYBOARDA - This is a WASD keyboard layout that is straight
// 7 - BUTTON_LAYOUT_DANCEPADA - This is a dance pad layout (must be used with `BUTTON_LAYOUT_DANCEPADB` in `BUTTON_LAYOUT_RIGHT`)
// The default `BUTTON_LAYOUT_RIGHT` is `BUTTON_LAYOUT_NOIR8` which will show eight buttons on the right hand side of the display.
// There are eleven options for `BUTTON_LAYOUT_RIGHT` currently:
// 1 - BUTTON_LAYOUT_ARCADE - This is a standard 8 button arcade layout
// 2 - BUTTON_LAYOUT_STICKLESSB - This is a basic stickless (all button) layout
// 3 - BUTTON_LAYOUT_BUTTONS_ANGLEDB - This is a standard 8 button arcade layout that is angled
// 4 - BUTTON_LAYOUT_VEWLIX - This is the standard 8 button Vewlix layout
// 5 - BUTTON_LAYOUT_VEWLIX7 - This is the standard 7 button Vewlix layout
// 6 - BUTTON_LAYOUT_CAPCOM - This is the standard 8 button Capcom layout
// 7 - BUTTON_LAYOUT_CAPCOM6 - This is the stndard 6 button Capcom layout
// 8 - BUTTON_LAYOUT_SEGA2P - This is the standard 8 button Sega2P layout
// 9 - BUTTON_LAYOUT_NOIR8 - This is the standard 8 button Noir layout
// 10 - BUTTON_LAYOUT_KEYBOARDB - This is a WASD keyboard layout that is straight
// 11 - BUTTON_LAYOUT_DANCEPADB - This is a dance pad layout (must be used with `BUTTON_LAYOUT_DANCEPADA` in `BUTTON_LAYOUT`)
// The default `SPLASH_MODE` is `NOSPLASH`.
// There are four options for `SPLASH_MODE` currently:
// 1 - `STATICSPLASH` - This will display the static splash image
// 2 - `CLOSEIN` - This will display the static splash image as a top and bottom coming together animation
// 3 - `CLOSEINCUSTOM` - This will display the custom splash image as a top and bottom coming together animation
// 4 - `NOSPLASH` - This will not display a splash screen on boot
// Special note - All of the splash screen images can be changed via `include/bitmaps.h`
#define HAS_I2C_DISPLAY -1
#define I2C_SDA_PIN 0
#define I2C_SCL_PIN 1
#define I2C_BLOCK i2c0
#define I2C_SPEED 400000
#define DISPLAY_FLIP 0
#define DISPLAY_INVERT 0
#define REVERSE_UP_DEFAULT 1
#define REVERSE_DOWN_DEFAULT 1
#define REVERSE_LEFT_DEFAULT 1
#define REVERSE_RIGHT_DEFAULT 1
#define BUTTON_LAYOUT BUTTON_LAYOUT_STICK
#define BUTTON_LAYOUT_RIGHT BUTTON_LAYOUT_VEWLIX
#define SPLASH_MODE SPLASH_MODE_NONE
#define SPLASH_CHOICE SPLASH_CHOICE_MAIN
#define SPLASH_DURATION 7500 // Duration in milliseconds
// Board LED Add-on Setting
// BOARD_LED_OFF - Turns the on-board LED off
// MODE_INDICATOR - On-board LED blinks on various frequencies depending
// on the current mode (config, normal, or no USB data)
// INPUT_TEST - Blinks whenever any input is made
#define BOARD_LED_TYPE ON_BOARD_LED_MODE_OFF
// Dual Directional Add-on Options
#define PIN_DUAL_DIRECTIONAL_UP -1
#define PIN_DUAL_DIRECTIONAL_DOWN -1
#define PIN_DUAL_DIRECTIONAL_LEFT -1
#define PIN_DUAL_DIRECTIONAL_RIGHT -1
#define DUAL_DIRECTIONAL_STICK_MODE DPAD_MODE_DIGITAL
#define DUAL_DIRECTIONAL_COMBINE_MODE DUAL_COMBINE_MODE_MIXED
// BOOTSEL Button Add-on setting
#define BOOTSEL_BUTTON_MASK 0 // 0 means none, get other mask from GamepadState.h
// Extra Button Add-on setting
#define EXTRA_BUTTON_MASK 0 // 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
// Keyboard Mapping Configuration
// List of HID keycodes can be located here: https://github.com/hathach/tinyusb/blob/3623ba1884ddff23e9b64766cb6dd032f1425846/src/class/hid/hid.h#L356
// Even for the modifier keys, HID_KEY entries should be used as the implementation expects those and will convert as necessary.
#define KEY_DPAD_UP HID_KEY_ARROW_UP // UP
#define KEY_DPAD_DOWN HID_KEY_ARROW_DOWN // DOWN
#define KEY_DPAD_LEFT HID_KEY_ARROW_LEFT // LEFT
#define KEY_DPAD_RIGHT HID_KEY_ARROW_RIGHT // RIGHT
#define KEY_BUTTON_B1 HID_KEY_SHIFT_LEFT // B1 / A / B / Cross / 2 / K1
#define KEY_BUTTON_B2 HID_KEY_Z // B2 / B / A / Circle / 3 / K2
#define KEY_BUTTON_B3 HID_KEY_CONTROL_LEFT // B3 / X / Y / Square / 1 / P1
#define KEY_BUTTON_B4 HID_KEY_ALT_LEFT // B4 / Y / X / Triangle / 4 / P2
#define KEY_BUTTON_L1 HID_KEY_C // L1 / LB / L / L1 / 5 / P4
#define KEY_BUTTON_R1 HID_KEY_SPACE // R1 / RB / R / R1 / 6 / P3
#define KEY_BUTTON_L2 HID_KEY_V // L2 / LT / ZL / L2 / 7 / K4
#define KEY_BUTTON_R2 HID_KEY_X // R2 / RT / ZR / R2 / 8 / K3
#define KEY_BUTTON_S1 HID_KEY_5 // S1 / Back / Minus / Select / 9 / Coin
#define KEY_BUTTON_S2 HID_KEY_1 // S2 / Start / Plus / Start / 10 / Start
#define KEY_BUTTON_L3 HID_KEY_EQUAL // L3 / LS / LS / L3 / 11 / LS
#define KEY_BUTTON_R3 HID_KEY_MINUS // R3 / RS / RS / R3 / 12 / RS
#define KEY_BUTTON_A1 HID_KEY_9 // A1 / Guide / Home / PS / 13 / ~
#define KEY_BUTTON_A2 HID_KEY_F2 // A2 / ~ / Capture / ~ / 14 / ~
// Hotkey Action Mapping
// Find the list of hotkey actions in GamepadEnums.h
#define HOTKEY_F1_UP_MASK GAMEPAD_MASK_UP
#define HOTKEY_F1_UP_ACTION HOTKEY_HOME_BUTTON
#define HOTKEY_F1_DOWN_MASK GAMEPAD_MASK_DOWN
#define HOTKEY_F1_DOWN_ACTION HOTKEY_DPAD_DIGITAL
#define HOTKEY_F1_LEFT_MASK GAMEPAD_MASK_LEFT
#define HOTKEY_F1_LEFT_ACTION HOTKEY_DPAD_LEFT_ANALOG
#define HOTKEY_F1_RIGHT_MASK GAMEPAD_MASK_RIGHT
#define HOTKEY_F1_RIGHT_ACTION HOTKEY_DPAD_RIGHT_ANALOG
#define HOTKEY_F2_UP_MASK GAMEPAD_MASK_UP
#define HOTKEY_F2_UP_ACTION HOTKEY_SOCD_UP_PRIORITY
#define HOTKEY_F2_DOWN_MASK GAMEPAD_MASK_DOWN
#define HOTKEY_F2_DOWN_ACTION HOTKEY_SOCD_NEUTRAL
#define HOTKEY_F2_LEFT_MASK GAMEPAD_MASK_LEFT
#define HOTKEY_F2_LEFT_ACTION HOTKEY_SOCD_LAST_INPUT
#define HOTKEY_F2_RIGHT_MASK GAMEPAD_MASK_RIGHT
#define HOTKEY_F2_RIGHT_ACTION HOTKEY_INVERT_Y_AXIS
#endif
/*
* SPDX-License-Identifier: MIT
* SPDX-FileCopyrightText: Copyright (c) 2021 Jason Skuby (mytechtoybox.com)
*/
#ifndef PICO_BOARD_CONFIG_H_
#define PICO_BOARD_CONFIG_H_
#include <GamepadEnums.h>
// This is the main pin definition section.
// This will let you specify which GPIO pin each button is assigned too.
// You can set any of the main pins as `-1` to disable it.
// The Turbo pin and LS + RS slider pins can also be set to `-1` to disable that functionality.
// Please note that only when `PIN_BUTTON_TURBO` is set to `-1` will the `T##` be removed from a connected display.
// Please note that only when `PIN_SLIDER_LS` and `PIN_SLIDER_RS` are set to `-1` will the button combo shortcut for DP/LS/RS work.
// The buttons are listed in GP2040 configuration, beside each the listed order is *GP2040 / Xinput / Switch / PS3 / Directinput / Arcade*
#define PIN_DPAD_UP 26 // UP
#define PIN_DPAD_DOWN 28 // DOWN
#define PIN_DPAD_LEFT 29 // LEFT
#define PIN_DPAD_RIGHT 27 // RIGHT
#define PIN_BUTTON_B1 1 // B1 / A / B / Cross / 2 / K1
#define PIN_BUTTON_B2 3 // B2 / B / A / Circle / 3 / K2
#define PIN_BUTTON_B3 0 // B3 / X / Y / Square / 1 / P1
#define PIN_BUTTON_B4 2 // B4 / Y / X / Triangle / 4 / P2
#define PIN_BUTTON_L1 5 // L1 / LB / L / L1 / 5 / P4
#define PIN_BUTTON_R1 4 // R1 / RB / R / R1 / 6 / P3
#define PIN_BUTTON_L2 6 // L2 / LT / ZL / L2 / 7 / K4
#define PIN_BUTTON_R2 7 // R2 / RT / ZR / R2 / 8 / K3
#define PIN_BUTTON_S1 8 // S1 / Back / Minus / Select / 9 / Coin
#define PIN_BUTTON_S2 9 // S2 / Start / Plus / Start / 10 / Start
#define PIN_BUTTON_L3 12 // L3 / LS / LS / L3 / 11 / LS
#define PIN_BUTTON_R3 13 // R3 / RS / RS / R3 / 12 / RS
#define PIN_BUTTON_A1 14 // A1 / Guide / Home / PS / 13 / ~
#define PIN_BUTTON_A2 15 // A2 / ~ / Capture / ~ / 14 / ~
#define PIN_BUTTON_TURBO -1 // Turbo
#define PIN_BUTTON_REVERSE -1 // UDLR Reverse
#define PIN_SLIDER_LS -1 // Left Stick Slider
#define PIN_SLIDER_RS -1 // Right Stick Slider
#define PIN_SLIDER_SOCD_ONE -1 // SOCD Slider Pin One
#define PIN_SLIDER_SOCD_TWO -1 // SOCD Slider Pin Two
// This is the SOCD section.
// SOCD stands for `simultaneous opposing cardinal directions`.
// There are three options for `DEFAULT_SOCD_MODE` currently:
// 1 - `SOCD_MODE_NEUTRAL` - This is a neutral SOCD. EG. when you press `up` + `down` no input will be registered.
// 2 - `SOCD_MODE_UP_PRIORITY` - This is up priority SOCD. EG. when you press `up` + `down` `up` will be registered.
// 3 - `SOCD_MODE_SECOND_INPUT_PRIORITY` - This is last priority SOCD. EG. when you press and hold `up` then press `down` `down` will be registered.
// 4 - `SOCD_MODE_FIRST_INPUT_PRIORITY` - This is first priority SOCD. EG. when you press and hold `up` then press `down` `up` will be registered.
#define DEFAULT_SOCD_MODE SOCD_MODE_NEUTRAL
// SOCD Slider Slot Defaults
#define SLIDER_SOCD_SLOT_ONE SOCD_MODE_UP_PRIORITY
#define SLIDER_SOCD_SLOT_TWO SOCD_MODE_SECOND_INPUT_PRIORITY
#define SLIDER_SOCD_SLOT_DEFAULT SOCD_MODE_NEUTRAL
#define DEFAULT_FORCED_SETUP_MODE FORCED_SETUP_MODE_OFF // FORCED_SETUP_MODE_OFF, FORCED_SETUP_MODE_LOCK_MODE_SWITCH, FORCED_SETUP_MODE_LOCK_WEB_CONFIG, FORCED_SETUP_MODE_LOCK_BOTH
#define DEFAULT_LOCK_HOTKEYS false // or true
// This is the LEDs section.
// The default `TURBO_LED_PIN` pin is set to `15` ( it is recommended to run through 3V3(OUT) with a resistor)
// The Turbo LED will flash at a speed consistant with the set speed of the Turbo when a Turbo button is active.
// It is recommended to disable the `TURBO_LED_PIN` by setting it to `-1` if you are sensitive of flashing lights.
// The default `BOARD_LEDS_PIN` pin is set to `28`.
// The board LED pin will allow you to connect addressible RGB LEDs on the Pico.
// Addressible RGB LEDs should be connected to the `VBUS` pin (#40), an avalible ground pin and the defined `BOARD_LEDS_PIN`.
// Special note - You should only ever use addressible RGB LEDs that are rated for 5v operation on the Pico.
// The defualt `LED_BRIGHTNESS_MAXIMUM` value is `50`.
// This will change how bright the LEDs are with `0` being off and `100` being full brightness.
// The minimum `LED_BRIGHTNESS_MAXIMUM` value is `0`.
// The maximum `LED_BRIGHTNESS_MAXIMUM` value is `100`.
// The defualt `LED_BRIGHTNESS_STEPS` value is `5`.
// This will change how many brightness steps there are when increasing or decreasing the brightness of the LEDs via the onboard shortcut.
// It is recommend to keep this value at `5` or `10`.
// The defualt `LED_FORMAT` is `LED_FORMAT_GRB`.
// You can also choose the `LED_FORMAT` of `LED_FORMAT_RGB` if your addressible RGB LEDs are not working as intended.
// The defualt `LEDS_PER_PIXEL` is set to `1`.
// This will change how many addressible RGB LEDs there are per button.
// The default LEDS_[BUTTON] is an order and has nothing to do with what GPIO pin something is connected to.
// Unless you are planning on running custom animations I would recommmend you leave this as is.
#define TURBO_LED_PIN -1
#define BOARD_LEDS_PIN -1
#define LED_BRIGHTNESS_MAXIMUM 50
#define LED_BRIGHTNESS_STEPS 5
#define LED_FORMAT LED_FORMAT_GRB
#define LEDS_PER_PIXEL 1
#define LEDS_DPAD_LEFT 0
#define LEDS_DPAD_DOWN 1
#define LEDS_DPAD_RIGHT 2
#define LEDS_DPAD_UP 3
#define LEDS_BUTTON_B3 4
#define LEDS_BUTTON_B4 5
#define LEDS_BUTTON_R1 6
#define LEDS_BUTTON_L1 7
#define LEDS_BUTTON_B1 8
#define LEDS_BUTTON_B2 9
#define LEDS_BUTTON_R2 10
#define LEDS_BUTTON_L2 11
// This is the Player LED section.
// In this section you can specify if Player LEDs will be active, and, if active, which pins will be used for them.
// The defualt is `PLED_TYPE_NONE` which will turn the Player LEDs off.
// The default pin for each Player LED is `-1` which disables it.
// To enable a `PLED#_PIN`, replace the `-1` with the GPIO pin number that is desired.
// There are three options for `PLED_TYPE` currently:
// 1 - `PLED_TYPE_NONE` - This will disable the Player LEDs
// 2 - `PLED_TYPE_PWM` - This will enable the Player LEDs ( it is recommended to run through 3V3(OUT) with a resistor)
// 3 - `PLED_TYPE_RGB` - This will enable the Player LEDs as addressible RGB LEDs (please not that this has not been implemented yet)
#define PLED_TYPE PLED_TYPE_NONE
#define PLED1_PIN -1
#define PLED2_PIN -1
#define PLED3_PIN -1
#define PLED4_PIN -1
// This is the Analog section.
// In this section you can specify if Analog is enabled, and, if endabled, which pins will be used for it.
// The default for `ANALOG_ADC_VRX` and `ANALOG_ADC_VRY` is `-1` which disables them.
// To enable a `ANALOG_ADC_VRX` and `ANALOG_ADC_VRY`, replace the `-1` with the GPIO pin numbers that are desired.
#define ANALOG_ADC_VRX -1
#define ANALOG_ADC_VRY -1
// Reverse Button section
#define REVERSE_LED_PIN -1
// This is the I2C Display section (commonly known as the OLED display section).
// In this section you can specify if a display as been enabled, which pins are assined to it, the block address and speed.
// The default for `HAS_I2C_DISPLAY` is `1` which enables it.
// To disable the display you can change `HAS_I2C_DISPLAY` to `-1`.
// The default `I2C_SDA_PIN` is `0`.
// The defualt `I2C_SCL_PIN` is `1`.
// The defualt `I2C_BLOCK` is `12c0`.
// If you change the `I2C_SDA_PIN` and `I2C_SCL_PIN` pin mapping, you may need to change the `I2C_BLOCK` as well.
// The defualt `I2C_SPEED` is `400000`.
// This should be more than fast enough for most displays.
// Some smaller displays (like 0.96" and 1.31") can go up to `800000` or even `1000000`.
// The default `DISPLAY_FLIP` is `0`.
// This can be changed to `1` to have the dispaly output flipped.
// The default `DISPLAY_INVERY` is `0`.
// This can be changed to `1` to have the color on the display inverted.
// The default `BUTTON_LAYOUT` is `BUTTON_LAYOUT_STICK` which will show an arcade stick on the left hand side of the display.
// There are seven options for `BUTTON_LAYOUT` currently:
// 1 - BUTTON_LAYOUT_STICK - This is a basic joystick layout
// 2 - BUTTON_LAYOUT_STICKLESS - This is a basic stickless (all button) layout
// 3 - BUTTON_LAYOUT_BUTTONS_ANGLED - This a WASD button layout that is angled
// 4 - BUTTON_LAYOUT_BUTTONS_BASIC - This a WASD button layout that is straight
// 5 - BUTTON_LAYOUT_KEYBOARD_ANGLED - This is a WASD keyboard layout that is angled
// 6 - BUTTON_LAYOUT_KEYBOARDA - This is a WASD keyboard layout that is straight
// 7 - BUTTON_LAYOUT_DANCEPADA - This is a dance pad layout (must be used with `BUTTON_LAYOUT_DANCEPADB` in `BUTTON_LAYOUT_RIGHT`)
// The default `BUTTON_LAYOUT_RIGHT` is `BUTTON_LAYOUT_NOIR8` which will show eight buttons on the right hand side of the display.
// There are eleven options for `BUTTON_LAYOUT_RIGHT` currently:
// 1 - BUTTON_LAYOUT_ARCADE - This is a standard 8 button arcade layout
// 2 - BUTTON_LAYOUT_STICKLESSB - This is a basic stickless (all button) layout
// 3 - BUTTON_LAYOUT_BUTTONS_ANGLEDB - This is a standard 8 button arcade layout that is angled
// 4 - BUTTON_LAYOUT_VEWLIX - This is the standard 8 button Vewlix layout
// 5 - BUTTON_LAYOUT_VEWLIX7 - This is the standard 7 button Vewlix layout
// 6 - BUTTON_LAYOUT_CAPCOM - This is the standard 8 button Capcom layout
// 7 - BUTTON_LAYOUT_CAPCOM6 - This is the stndard 6 button Capcom layout
// 8 - BUTTON_LAYOUT_SEGA2P - This is the standard 8 button Sega2P layout
// 9 - BUTTON_LAYOUT_NOIR8 - This is the standard 8 button Noir layout
// 10 - BUTTON_LAYOUT_KEYBOARDB - This is a WASD keyboard layout that is straight
// 11 - BUTTON_LAYOUT_DANCEPADB - This is a dance pad layout (must be used with `BUTTON_LAYOUT_DANCEPADA` in `BUTTON_LAYOUT`)
// The default `SPLASH_MODE` is `NOSPLASH`.
// There are four options for `SPLASH_MODE` currently:
// 1 - `STATICSPLASH` - This will display the static splash image
// 2 - `CLOSEIN` - This will display the static splash image as a top and bottom coming together animation
// 3 - `CLOSEINCUSTOM` - This will display the custom splash image as a top and bottom coming together animation
// 4 - `NOSPLASH` - This will not display a splash screen on boot
// Special note - All of the splash screen images can be changed via `include/bitmaps.h`
#define HAS_I2C_DISPLAY -1
#define I2C_SDA_PIN 0
#define I2C_SCL_PIN 1
#define I2C_BLOCK i2c0
#define I2C_SPEED 400000
#define DISPLAY_FLIP 0
#define DISPLAY_INVERT 0
#define REVERSE_UP_DEFAULT 1
#define REVERSE_DOWN_DEFAULT 1
#define REVERSE_LEFT_DEFAULT 1
#define REVERSE_RIGHT_DEFAULT 1
#define BUTTON_LAYOUT BUTTON_LAYOUT_STICK
#define BUTTON_LAYOUT_RIGHT BUTTON_LAYOUT_VEWLIX
#define SPLASH_MODE SPLASH_MODE_NONE
#define SPLASH_CHOICE SPLASH_CHOICE_MAIN
#define SPLASH_DURATION 7500 // Duration in milliseconds
// Board LED Add-on Setting
// BOARD_LED_OFF - Turns the on-board LED off
// MODE_INDICATOR - On-board LED blinks on various frequencies depending
// on the current mode (config, normal, or no USB data)
// INPUT_TEST - Blinks whenever any input is made
#define BOARD_LED_TYPE ON_BOARD_LED_MODE_OFF
// Dual Directional Add-on Options
#define PIN_DUAL_DIRECTIONAL_UP -1
#define PIN_DUAL_DIRECTIONAL_DOWN -1
#define PIN_DUAL_DIRECTIONAL_LEFT -1
#define PIN_DUAL_DIRECTIONAL_RIGHT -1
#define DUAL_DIRECTIONAL_STICK_MODE DPAD_MODE_DIGITAL
#define DUAL_DIRECTIONAL_COMBINE_MODE DUAL_COMBINE_MODE_MIXED
// BOOTSEL Button Add-on setting
#define BOOTSEL_BUTTON_MASK 0 // 0 means none, get other mask from GamepadState.h
// Extra Button Add-on setting
#define EXTRA_BUTTON_MASK 0 // 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
// Keyboard Mapping Configuration
// List of HID keycodes can be located here: https://github.com/hathach/tinyusb/blob/3623ba1884ddff23e9b64766cb6dd032f1425846/src/class/hid/hid.h#L356
// Even for the modifier keys, HID_KEY entries should be used as the implementation expects those and will convert as necessary.
#define KEY_DPAD_UP HID_KEY_ARROW_UP // UP
#define KEY_DPAD_DOWN HID_KEY_ARROW_DOWN // DOWN
#define KEY_DPAD_LEFT HID_KEY_ARROW_LEFT // LEFT
#define KEY_DPAD_RIGHT HID_KEY_ARROW_RIGHT // RIGHT
#define KEY_BUTTON_B1 HID_KEY_SHIFT_LEFT // B1 / A / B / Cross / 2 / K1
#define KEY_BUTTON_B2 HID_KEY_Z // B2 / B / A / Circle / 3 / K2
#define KEY_BUTTON_B3 HID_KEY_CONTROL_LEFT // B3 / X / Y / Square / 1 / P1
#define KEY_BUTTON_B4 HID_KEY_ALT_LEFT // B4 / Y / X / Triangle / 4 / P2
#define KEY_BUTTON_L1 HID_KEY_C // L1 / LB / L / L1 / 5 / P4
#define KEY_BUTTON_R1 HID_KEY_SPACE // R1 / RB / R / R1 / 6 / P3
#define KEY_BUTTON_L2 HID_KEY_V // L2 / LT / ZL / L2 / 7 / K4
#define KEY_BUTTON_R2 HID_KEY_X // R2 / RT / ZR / R2 / 8 / K3
#define KEY_BUTTON_S1 HID_KEY_5 // S1 / Back / Minus / Select / 9 / Coin
#define KEY_BUTTON_S2 HID_KEY_1 // S2 / Start / Plus / Start / 10 / Start
#define KEY_BUTTON_L3 HID_KEY_EQUAL // L3 / LS / LS / L3 / 11 / LS
#define KEY_BUTTON_R3 HID_KEY_MINUS // R3 / RS / RS / R3 / 12 / RS
#define KEY_BUTTON_A1 HID_KEY_9 // A1 / Guide / Home / PS / 13 / ~
#define KEY_BUTTON_A2 HID_KEY_F2 // A2 / ~ / Capture / ~ / 14 / ~
// Hotkey Action Mapping
// Find the list of hotkey actions in GamepadEnums.h
#define HOTKEY_F1_UP_MASK GAMEPAD_MASK_UP
#define HOTKEY_F1_UP_ACTION HOTKEY_HOME_BUTTON
#define HOTKEY_F1_DOWN_MASK GAMEPAD_MASK_DOWN
#define HOTKEY_F1_DOWN_ACTION HOTKEY_DPAD_DIGITAL
#define HOTKEY_F1_LEFT_MASK GAMEPAD_MASK_LEFT
#define HOTKEY_F1_LEFT_ACTION HOTKEY_DPAD_LEFT_ANALOG
#define HOTKEY_F1_RIGHT_MASK GAMEPAD_MASK_RIGHT
#define HOTKEY_F1_RIGHT_ACTION HOTKEY_DPAD_RIGHT_ANALOG
#define HOTKEY_F2_UP_MASK GAMEPAD_MASK_UP
#define HOTKEY_F2_UP_ACTION HOTKEY_SOCD_UP_PRIORITY
#define HOTKEY_F2_DOWN_MASK GAMEPAD_MASK_DOWN
#define HOTKEY_F2_DOWN_ACTION HOTKEY_SOCD_NEUTRAL
#define HOTKEY_F2_LEFT_MASK GAMEPAD_MASK_LEFT
#define HOTKEY_F2_LEFT_ACTION HOTKEY_SOCD_LAST_INPUT
#define HOTKEY_F2_RIGHT_MASK GAMEPAD_MASK_RIGHT
#define HOTKEY_F2_RIGHT_ACTION HOTKEY_INVERT_Y_AXIS
#endif

View File

@@ -1,6 +1,6 @@
# GP2040 Configuration for the Stress Fightpad
![Stress Fightpad](assets/stress-00.jpg)
Configuration for the [Stress Fightpad](https://github.com/GroooveBob/Stress). Configuration uses the same pinout as the Waveshare RP2040 Zero.
# GP2040 Configuration for the Stress Fightpad
![Stress Fightpad](assets/stress-00.jpg)
Configuration for the [Stress Fightpad](https://github.com/GroooveBob/Stress). Configuration uses the same pinout as the Waveshare RP2040 Zero.

View File

@@ -1,5 +1,5 @@
[env:Stress]
upload_port = .pio/build/Stress/
build_flags =
${env.build_flags}
-I configs/Stress/
[env:Stress]
upload_port = .pio/build/Stress/
build_flags =
${env.build_flags}
-I configs/Stress/

View File

@@ -1,88 +1,88 @@
/*
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
// -----------------------------------------------------
// NOTE: THIS HEADER IS ALSO INCLUDED BY ASSEMBLER SO
// SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES
// -----------------------------------------------------
#ifndef _BOARDS_STRESS_H
#define _BOARDS_STRESS_H
// For board detection
#define STRESS
//For crappy crystal
#ifndef PICO_XOSC_STARTUP_DELAY_MULTIPLIER
#define PICO_XOSC_STARTUP_DELAY_MULTIPLIER 64
#endif
// --- UART ---
#ifndef PICO_DEFAULT_UART
#define PICO_DEFAULT_UART 0
#endif
#ifndef PICO_DEFAULT_UART_TX_PIN
#define PICO_DEFAULT_UART_TX_PIN 0
#endif
#ifndef PICO_DEFAULT_UART_RX_PIN
#define PICO_DEFAULT_UART_RX_PIN 1
#endif
// --- LED ---
#ifndef PICO_DEFAULT_LED_PIN
#define PICO_DEFAULT_LED_PIN 25
#endif
// no PICO_DEFAULT_WS2812_PIN
// --- I2C ---
#ifndef PICO_DEFAULT_I2C
#define PICO_DEFAULT_I2C 0
#endif
#ifndef PICO_DEFAULT_I2C_SDA_PIN
#define PICO_DEFAULT_I2C_SDA_PIN 4
#endif
#ifndef PICO_DEFAULT_I2C_SCL_PIN
#define PICO_DEFAULT_I2C_SCL_PIN 5
#endif
// --- SPI ---
#ifndef PICO_DEFAULT_SPI
#define PICO_DEFAULT_SPI 0
#endif
#ifndef PICO_DEFAULT_SPI_SCK_PIN
#define PICO_DEFAULT_SPI_SCK_PIN 18
#endif
#ifndef PICO_DEFAULT_SPI_TX_PIN
#define PICO_DEFAULT_SPI_TX_PIN 19
#endif
#ifndef PICO_DEFAULT_SPI_RX_PIN
#define PICO_DEFAULT_SPI_RX_PIN 16
#endif
#ifndef PICO_DEFAULT_SPI_CSN_PIN
#define PICO_DEFAULT_SPI_CSN_PIN 17
#endif
// --- FLASH ---
#define PICO_BOOT_STAGE2_CHOOSE_W25Q080 1
#ifndef PICO_FLASH_SPI_CLKDIV
#define PICO_FLASH_SPI_CLKDIV 2
#endif
#ifndef PICO_FLASH_SIZE_BYTES
#define PICO_FLASH_SIZE_BYTES (2 * 1024 * 1024)
#endif
// Drive high to force power supply into PWM mode (lower ripple on 3V3 at light loads)
#define PICO_SMPS_MODE_PIN 23
#ifndef PICO_RP2040_B0_SUPPORTED
#define PICO_RP2040_B0_SUPPORTED 1
#endif
#endif
/*
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
// -----------------------------------------------------
// NOTE: THIS HEADER IS ALSO INCLUDED BY ASSEMBLER SO
// SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES
// -----------------------------------------------------
#ifndef _BOARDS_STRESS_H
#define _BOARDS_STRESS_H
// For board detection
#define STRESS
//For crappy crystal
#ifndef PICO_XOSC_STARTUP_DELAY_MULTIPLIER
#define PICO_XOSC_STARTUP_DELAY_MULTIPLIER 64
#endif
// --- UART ---
#ifndef PICO_DEFAULT_UART
#define PICO_DEFAULT_UART 0
#endif
#ifndef PICO_DEFAULT_UART_TX_PIN
#define PICO_DEFAULT_UART_TX_PIN 0
#endif
#ifndef PICO_DEFAULT_UART_RX_PIN
#define PICO_DEFAULT_UART_RX_PIN 1
#endif
// --- LED ---
#ifndef PICO_DEFAULT_LED_PIN
#define PICO_DEFAULT_LED_PIN 25
#endif
// no PICO_DEFAULT_WS2812_PIN
// --- I2C ---
#ifndef PICO_DEFAULT_I2C
#define PICO_DEFAULT_I2C 0
#endif
#ifndef PICO_DEFAULT_I2C_SDA_PIN
#define PICO_DEFAULT_I2C_SDA_PIN 4
#endif
#ifndef PICO_DEFAULT_I2C_SCL_PIN
#define PICO_DEFAULT_I2C_SCL_PIN 5
#endif
// --- SPI ---
#ifndef PICO_DEFAULT_SPI
#define PICO_DEFAULT_SPI 0
#endif
#ifndef PICO_DEFAULT_SPI_SCK_PIN
#define PICO_DEFAULT_SPI_SCK_PIN 18
#endif
#ifndef PICO_DEFAULT_SPI_TX_PIN
#define PICO_DEFAULT_SPI_TX_PIN 19
#endif
#ifndef PICO_DEFAULT_SPI_RX_PIN
#define PICO_DEFAULT_SPI_RX_PIN 16
#endif
#ifndef PICO_DEFAULT_SPI_CSN_PIN
#define PICO_DEFAULT_SPI_CSN_PIN 17
#endif
// --- FLASH ---
#define PICO_BOOT_STAGE2_CHOOSE_W25Q080 1
#ifndef PICO_FLASH_SPI_CLKDIV
#define PICO_FLASH_SPI_CLKDIV 2
#endif
#ifndef PICO_FLASH_SIZE_BYTES
#define PICO_FLASH_SIZE_BYTES (2 * 1024 * 1024)
#endif
// Drive high to force power supply into PWM mode (lower ripple on 3V3 at light loads)
#define PICO_SMPS_MODE_PIN 23
#ifndef PICO_RP2040_B0_SUPPORTED
#define PICO_RP2040_B0_SUPPORTED 1
#endif
#endif

View File

@@ -1,37 +1,37 @@
#ifndef PS4MODE_H_
#define PS4MODE_H_
#include "gpaddon.h"
#include "storagemanager.h"
#include "mbedtls/rsa.h"
#ifndef PS4MODE_ADDON_ENABLED
#define PS4MODE_ADDON_ENABLED 0
#endif
// Turbo Module Name
#define PS4ModeName "PS4Mode"
class PS4ModeAddon : public GPAddon {
public:
virtual bool available();
virtual void setup(); // TURBO Button Setup
virtual void preprocess() {}
virtual void process(); // TURBO Setting of buttons (Enable/Disable)
virtual std::string name() { return PS4ModeName; }
private:
struct mbedtls_rsa_context rsa_context;
mbedtls_mpi_uint bytesN[64] = {};
mbedtls_mpi_uint bytesE[1] = {};
mbedtls_mpi_uint bytesD[64] = {};
mbedtls_mpi_uint bytesP[32] = {};
mbedtls_mpi_uint bytesQ[32] = {};
mbedtls_mpi_uint bytesDP[32] = {};
mbedtls_mpi_uint bytesDQ[32] = {};
mbedtls_mpi_uint bytesQP[32] = {};
mbedtls_mpi_uint bytesRN[64] = {};
uint8_t hashed_nonce[32] = {};
};
#endif // PS4MODE_H_
#ifndef PS4MODE_H_
#define PS4MODE_H_
#include "gpaddon.h"
#include "storagemanager.h"
#include "mbedtls/rsa.h"
#ifndef PS4MODE_ADDON_ENABLED
#define PS4MODE_ADDON_ENABLED 0
#endif
// Turbo Module Name
#define PS4ModeName "PS4Mode"
class PS4ModeAddon : public GPAddon {
public:
virtual bool available();
virtual void setup(); // TURBO Button Setup
virtual void preprocess() {}
virtual void process(); // TURBO Setting of buttons (Enable/Disable)
virtual std::string name() { return PS4ModeName; }
private:
struct mbedtls_rsa_context rsa_context;
mbedtls_mpi_uint bytesN[64] = {};
mbedtls_mpi_uint bytesE[1] = {};
mbedtls_mpi_uint bytesD[64] = {};
mbedtls_mpi_uint bytesP[32] = {};
mbedtls_mpi_uint bytesQ[32] = {};
mbedtls_mpi_uint bytesDP[32] = {};
mbedtls_mpi_uint bytesDQ[32] = {};
mbedtls_mpi_uint bytesQP[32] = {};
mbedtls_mpi_uint bytesRN[64] = {};
uint8_t hashed_nonce[32] = {};
};
#endif // PS4MODE_H_

View File

@@ -1,135 +1,135 @@
#ifndef _BASE64_H_
#define _BASE64_H_
/**
* The MIT License (MIT)
* Copyright (c) 2016 tomykaira
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <string>
class Base64 {
public:
static std::string Encode(const char* dataPtr, size_t dataLen) {
static constexpr char sEncodingTable[] = {
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '0', '1', '2', '3',
'4', '5', '6', '7', '8', '9', '+', '/'
};
size_t out_len = 4 * ((dataLen + 2) / 3);
std::string ret;
ret.resize(out_len);
size_t i = 0;
char *p = ret.data();
if (dataLen >= 2) {
for (; i < dataLen - 2; i += 3) {
*p++ = sEncodingTable[(dataPtr[i] >> 2) & 0x3F];
*p++ = sEncodingTable[((dataPtr[i] & 0x3) << 4) | ((int) (dataPtr[i + 1] & 0xF0) >> 4)];
*p++ = sEncodingTable[((dataPtr[i + 1] & 0xF) << 2) | ((int) (dataPtr[i + 2] & 0xC0) >> 6)];
*p++ = sEncodingTable[dataPtr[i + 2] & 0x3F];
}
}
if (i < dataLen) {
*p++ = sEncodingTable[(dataPtr[i] >> 2) & 0x3F];
if (i == (dataLen - 1)) {
*p++ = sEncodingTable[((dataPtr[i] & 0x3) << 4)];
*p++ = '=';
}
else {
*p++ = sEncodingTable[((dataPtr[i] & 0x3) << 4) | ((int) (dataPtr[i + 1] & 0xF0) >> 4)];
*p++ = sEncodingTable[((dataPtr[i + 1] & 0xF) << 2)];
}
*p++ = '=';
}
return ret;
}
static std::string Encode(const std::string data) {
return Encode(data.data(), data.length());
}
static bool Decode(const char* dataPtr, size_t dataLen, std::string& out) {
static constexpr unsigned char kDecodingTable[] = {
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64,
64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64,
64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64
};
if (dataLen % 4 != 0)
{
out.clear();
return false;
}
size_t out_len = dataLen / 4 * 3;
if (dataLen >= 1 && dataPtr[dataLen - 1] == '=') out_len--;
if (dataLen >= 2 && dataPtr[dataLen - 2] == '=') out_len--;
out.resize(out_len);
for (size_t i = 0, j = 0; i < dataLen;) {
uint32_t a = dataPtr[i] == '=' ? 0 & i++ : kDecodingTable[static_cast<int>(dataPtr[i++])];
uint32_t b = dataPtr[i] == '=' ? 0 & i++ : kDecodingTable[static_cast<int>(dataPtr[i++])];
uint32_t c = dataPtr[i] == '=' ? 0 & i++ : kDecodingTable[static_cast<int>(dataPtr[i++])];
uint32_t d = dataPtr[i] == '=' ? 0 & i++ : kDecodingTable[static_cast<int>(dataPtr[i++])];
uint32_t triple = (a << 3 * 6) + (b << 2 * 6) + (c << 1 * 6) + (d << 0 * 6);
if (j < out_len) out[j++] = (triple >> 2 * 8) & 0xFF;
if (j < out_len) out[j++] = (triple >> 1 * 8) & 0xFF;
if (j < out_len) out[j++] = (triple >> 0 * 8) & 0xFF;
}
return true;
}
static bool Decode(const std::string& input, std::string& out) {
return Decode(input.data(), input.length(), out);
}
};
#ifndef _BASE64_H_
#define _BASE64_H_
/**
* The MIT License (MIT)
* Copyright (c) 2016 tomykaira
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <string>
class Base64 {
public:
static std::string Encode(const char* dataPtr, size_t dataLen) {
static constexpr char sEncodingTable[] = {
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '0', '1', '2', '3',
'4', '5', '6', '7', '8', '9', '+', '/'
};
size_t out_len = 4 * ((dataLen + 2) / 3);
std::string ret;
ret.resize(out_len);
size_t i = 0;
char *p = ret.data();
if (dataLen >= 2) {
for (; i < dataLen - 2; i += 3) {
*p++ = sEncodingTable[(dataPtr[i] >> 2) & 0x3F];
*p++ = sEncodingTable[((dataPtr[i] & 0x3) << 4) | ((int) (dataPtr[i + 1] & 0xF0) >> 4)];
*p++ = sEncodingTable[((dataPtr[i + 1] & 0xF) << 2) | ((int) (dataPtr[i + 2] & 0xC0) >> 6)];
*p++ = sEncodingTable[dataPtr[i + 2] & 0x3F];
}
}
if (i < dataLen) {
*p++ = sEncodingTable[(dataPtr[i] >> 2) & 0x3F];
if (i == (dataLen - 1)) {
*p++ = sEncodingTable[((dataPtr[i] & 0x3) << 4)];
*p++ = '=';
}
else {
*p++ = sEncodingTable[((dataPtr[i] & 0x3) << 4) | ((int) (dataPtr[i + 1] & 0xF0) >> 4)];
*p++ = sEncodingTable[((dataPtr[i + 1] & 0xF) << 2)];
}
*p++ = '=';
}
return ret;
}
static std::string Encode(const std::string data) {
return Encode(data.data(), data.length());
}
static bool Decode(const char* dataPtr, size_t dataLen, std::string& out) {
static constexpr unsigned char kDecodingTable[] = {
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64,
64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64,
64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64
};
if (dataLen % 4 != 0)
{
out.clear();
return false;
}
size_t out_len = dataLen / 4 * 3;
if (dataLen >= 1 && dataPtr[dataLen - 1] == '=') out_len--;
if (dataLen >= 2 && dataPtr[dataLen - 2] == '=') out_len--;
out.resize(out_len);
for (size_t i = 0, j = 0; i < dataLen;) {
uint32_t a = dataPtr[i] == '=' ? 0 & i++ : kDecodingTable[static_cast<int>(dataPtr[i++])];
uint32_t b = dataPtr[i] == '=' ? 0 & i++ : kDecodingTable[static_cast<int>(dataPtr[i++])];
uint32_t c = dataPtr[i] == '=' ? 0 & i++ : kDecodingTable[static_cast<int>(dataPtr[i++])];
uint32_t d = dataPtr[i] == '=' ? 0 & i++ : kDecodingTable[static_cast<int>(dataPtr[i++])];
uint32_t triple = (a << 3 * 6) + (b << 2 * 6) + (c << 1 * 6) + (d << 0 * 6);
if (j < out_len) out[j++] = (triple >> 2 * 8) & 0xFF;
if (j < out_len) out[j++] = (triple >> 1 * 8) & 0xFF;
if (j < out_len) out[j++] = (triple >> 0 * 8) & 0xFF;
}
return true;
}
static bool Decode(const std::string& input, std::string& out) {
return Decode(input.data(), input.length(), out);
}
};
#endif /* _BASE64_H_ */

View File

@@ -1,305 +1,305 @@
/*
* SPDX-License-Identifier: MIT
* SPDX-FileCopyrightText: Copyright (c) 2021 Jason Skuby (mytechtoybox.com)
*/
#pragma once
#include <stdint.h>
#define HID_ENDPOINT_SIZE 64
// Mayflash
//#define PS4_VENDOR_ID 0x33df
//#define PS4_PRODUCT_ID 0x0011
// Razer Panthera
#define PS4_VENDOR_ID 0x1532
#define PS4_PRODUCT_ID 0x0401
// Madcatz Fightstick Alpha PS4
//#define PS4_VENDOR_ID 0x0738
//#define PS4_PRODUCT_ID 0x8180
/**************************************************************************
*
* Endpoint Buffer Configuration
*
**************************************************************************/
#define ENDPOINT0_SIZE 64
#define GAMEPAD_INTERFACE 0
#define GAMEPAD_ENDPOINT 1
#define GAMEPAD_SIZE 64
#define LSB(n) (n & 255)
#define MSB(n) ((n >> 8) & 255)
// HAT report (4 bits)
#define HID_HAT_UP 0x00
#define HID_HAT_UPRIGHT 0x01
#define HID_HAT_RIGHT 0x02
#define HID_HAT_DOWNRIGHT 0x03
#define HID_HAT_DOWN 0x04
#define HID_HAT_DOWNLEFT 0x05
#define HID_HAT_LEFT 0x06
#define HID_HAT_UPLEFT 0x07
#define HID_HAT_NOTHING 0x08
#define PS4_HAT_NOTHING 0x0F
// Button report (16 bits)
#define HID_MASK_SQUARE (1U << 0)
#define HID_MASK_CROSS (1U << 1)
#define HID_MASK_CIRCLE (1U << 2)
#define HID_MASK_TRIANGLE (1U << 3)
#define HID_MASK_L1 (1U << 4)
#define HID_MASK_R1 (1U << 5)
#define HID_MASK_L2 (1U << 6)
#define HID_MASK_R2 (1U << 7)
#define HID_MASK_SELECT (1U << 8)
#define HID_MASK_START (1U << 9)
#define HID_MASK_L3 (1U << 10)
#define HID_MASK_R3 (1U << 11)
#define HID_MASK_PS (1U << 12)
#define HID_MASK_TP (1U << 13)
// Switch analog sticks only report 8 bits
#define HID_JOYSTICK_MIN 0x00
#define HID_JOYSTICK_MID 0x80
#define HID_JOYSTICK_MAX 0xFF
struct TouchpadXY {
uint8_t counter : 7;
uint8_t unpressed : 1;
// 12 bit X, followed by 12 bit Y
uint8_t data[3];
void set_x(uint16_t x) {
data[0] = x & 0xff;
data[1] = (data[1] & 0xf0) | ((x >> 8) & 0xf);
}
void set_y(uint16_t y) {
data[1] = (data[1] & 0x0f) | ((y & 0xf) << 4);
data[2] = y >> 4;
return;
}
};
struct TouchpadData {
TouchpadXY p1;
TouchpadXY p2;
};
typedef struct __attribute__((packed)) {
uint8_t report_id;
uint8_t left_stick_x;
uint8_t left_stick_y;
uint8_t right_stick_x;
uint8_t right_stick_y;
// 4 bits for the d-pad.
uint32_t dpad : 4;
// 14 bits for buttons.
uint32_t button_west : 1;
uint32_t button_south : 1;
uint32_t button_east : 1;
uint32_t button_north : 1;
uint32_t button_l1 : 1;
uint32_t button_r1 : 1;
uint32_t button_l2 : 1;
uint32_t button_r2 : 1;
uint32_t button_select : 1;
uint32_t button_start : 1;
uint32_t button_l3 : 1;
uint32_t button_r3 : 1;
uint32_t button_home : 1;
uint32_t button_touchpad : 1;
// 6 bit report counter.
uint32_t report_counter : 6;
uint32_t left_trigger : 8;
uint32_t right_trigger : 8;
uint32_t padding : 24;
uint8_t mystery[22];
TouchpadData touchpad_data;
uint8_t mystery_2[21];
} PS4Report;
static const uint8_t ps4_string_language[] = { 0x09, 0x04 };
static const uint8_t ps4_string_manufacturer[] = "Open Stick Community";
static const uint8_t ps4_string_product[] = "GP2040-CE (PS4)";
static const uint8_t ps4_string_version[] = "1.0";
static const uint8_t *ps4_string_descriptors[] =
{
ps4_string_language,
ps4_string_manufacturer,
ps4_string_product,
ps4_string_version
};
static const uint8_t ps4_device_descriptor[] =
{
18, // bLength
1, // bDescriptorType
0x00, 0x02, // bcdUSB
0, // bDeviceClass
0, // bDeviceSubClass
0, // bDeviceProtocol
ENDPOINT0_SIZE, // bMaxPacketSize0
LSB(PS4_VENDOR_ID), MSB(PS4_VENDOR_ID), // idVendor
LSB(PS4_PRODUCT_ID), MSB(PS4_PRODUCT_ID), // idProduct
0x00, 0x01, // bcdDevice
1, // iManufacturer
2, // iProduct
0, // iSerialNumber
1 // bNumConfigurations
};
static const uint8_t ps4_report_descriptor[] =
{
0x05, 0x01, // Usage Page (Generic Desktop Ctrls)
0x09, 0x05, // Usage (Game Pad)
0xA1, 0x01, // Collection (Application)
0x85, 0x01, // Report ID (1)
0x09, 0x30, // Usage (X)
0x09, 0x31, // Usage (Y)
0x09, 0x32, // Usage (Z)
0x09, 0x35, // Usage (Rz)
0x15, 0x00, // Logical Minimum (0)
0x26, 0xFF, 0x00, // Logical Maximum (255)
0x75, 0x08, // Report Size (8)
0x95, 0x04, // Report Count (4)
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x09, 0x39, // Usage (Hat switch)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x07, // Logical Maximum (7)
0x35, 0x00, // Physical Minimum (0)
0x46, 0x3B, 0x01, // Physical Maximum (315)
0x65, 0x14, // Unit (System: English Rotation, Length: Centimeter)
0x75, 0x04, // Report Size (4)
0x95, 0x01, // Report Count (1)
0x81, 0x42, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,Null State)
0x65, 0x00, // Unit (None)
0x05, 0x09, // Usage Page (Button)
0x19, 0x01, // Usage Minimum (0x01)
0x29, 0x0E, // Usage Maximum (0x0E)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1)
0x75, 0x01, // Report Size (1)
0x95, 0x0E, // Report Count (14)
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x06, 0x00, 0xFF, // Usage Page (Vendor Defined 0xFF00)
0x09, 0x20, // Usage (0x20)
0x75, 0x06, // Report Size (6)
0x95, 0x01, // Report Count (1)
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x05, 0x01, // Usage Page (Generic Desktop Ctrls)
0x09, 0x33, // Usage (Rx)
0x09, 0x34, // Usage (Ry)
0x15, 0x00, // Logical Minimum (0)
0x26, 0xFF, 0x00, // Logical Maximum (255)
0x75, 0x08, // Report Size (8)
0x95, 0x02, // Report Count (2)
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x06, 0x00, 0xFF, // Usage Page (Vendor Defined 0xFF00)
0x09, 0x21, // Usage (0x21)
0x95, 0x36, // Report Count (54)
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x85, 0x05, // Report ID (5)
0x09, 0x22, // Usage (0x22)
0x95, 0x1F, // Report Count (31)
0x91, 0x02, // Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x03, // Report ID (3)
0x0A, 0x21, 0x27, // Usage (0x2721)
0x95, 0x2F, // Report Count (47)
0xB1, 0x02, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0, // End Collection
0x06, 0xF0, 0xFF, // Usage Page (Vendor Defined 0xFFF0)
0x09, 0x40, // Usage (0x40)
0xA1, 0x01, // Collection (Application)
0x85, 0xF0, // Report ID (-16) AUTH F0
0x09, 0x47, // Usage (0x47)
0x95, 0x3F, // Report Count (63)
0xB1, 0x02, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xF1, // Report ID (-15) AUTH F1
0x09, 0x48, // Usage (0x48)
0x95, 0x3F, // Report Count (63)
0xB1, 0x02, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xF2, // Report ID (-14) AUTH F2
0x09, 0x49, // Usage (0x49)
0x95, 0x0F, // Report Count (15)
0xB1, 0x02, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xF3, // Report ID (-13) Auth F3 (Reset)
0x0A, 0x01, 0x47, // Usage (0x4701)
0x95, 0x07, // Report Count (7)
0xB1, 0x02, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0, // End Collection
};
static const uint8_t ps4_hid_descriptor[] =
{
0x09, // bLength
0x21, // bDescriptorType (HID)
0x11, 0x01, // bcdHID 1.11
0x00, // bCountryCode
0x01, // bNumDescriptors
0x22, // bDescriptorType[0] (HID)
sizeof(ps4_report_descriptor), 0x00, // wDescriptorLength[0] 90
};
#define CONFIG1_DESC_SIZE (9+9+9+7)
static const uint8_t ps4_configuration_descriptor[] =
{
// configuration descriptor, USB spec 9.6.3, page 264-266, Table 9-10
9, // bLength;
2, // bDescriptorType;
LSB(CONFIG1_DESC_SIZE), // wTotalLength
MSB(CONFIG1_DESC_SIZE),
1, // bNumInterfaces
1, // bConfigurationValue
0, // iConfiguration
0x80, // bmAttributes
50, // bMaxPower
// interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
9, // bLength
4, // bDescriptorType
GAMEPAD_INTERFACE, // bInterfaceNumber
0, // bAlternateSetting
1, // bNumEndpoints
0x03, // bInterfaceClass (0x03 = HID)
0x00, // bInterfaceSubClass (0x00 = No Boot)
0x00, // bInterfaceProtocol (0x00 = No Protocol)
0, // iInterface
// HID interface descriptor, HID 1.11 spec, section 6.2.1
9, // bLength
0x21, // bDescriptorType
0x11, 0x01, // bcdHID
0, // bCountryCode
1, // bNumDescriptors
0x22, // bDescriptorType
sizeof(ps4_report_descriptor), // wDescriptorLength
0,
// endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
7, // bLength
5, // bDescriptorType
GAMEPAD_ENDPOINT | 0x80, // bEndpointAddress
0x03, // bmAttributes (0x03=intr)
GAMEPAD_SIZE, 0, // wMaxPacketSize
1 // bInterval (1 ms)
/*
* SPDX-License-Identifier: MIT
* SPDX-FileCopyrightText: Copyright (c) 2021 Jason Skuby (mytechtoybox.com)
*/
#pragma once
#include <stdint.h>
#define HID_ENDPOINT_SIZE 64
// Mayflash
//#define PS4_VENDOR_ID 0x33df
//#define PS4_PRODUCT_ID 0x0011
// Razer Panthera
#define PS4_VENDOR_ID 0x1532
#define PS4_PRODUCT_ID 0x0401
// Madcatz Fightstick Alpha PS4
//#define PS4_VENDOR_ID 0x0738
//#define PS4_PRODUCT_ID 0x8180
/**************************************************************************
*
* Endpoint Buffer Configuration
*
**************************************************************************/
#define ENDPOINT0_SIZE 64
#define GAMEPAD_INTERFACE 0
#define GAMEPAD_ENDPOINT 1
#define GAMEPAD_SIZE 64
#define LSB(n) (n & 255)
#define MSB(n) ((n >> 8) & 255)
// HAT report (4 bits)
#define HID_HAT_UP 0x00
#define HID_HAT_UPRIGHT 0x01
#define HID_HAT_RIGHT 0x02
#define HID_HAT_DOWNRIGHT 0x03
#define HID_HAT_DOWN 0x04
#define HID_HAT_DOWNLEFT 0x05
#define HID_HAT_LEFT 0x06
#define HID_HAT_UPLEFT 0x07
#define HID_HAT_NOTHING 0x08
#define PS4_HAT_NOTHING 0x0F
// Button report (16 bits)
#define HID_MASK_SQUARE (1U << 0)
#define HID_MASK_CROSS (1U << 1)
#define HID_MASK_CIRCLE (1U << 2)
#define HID_MASK_TRIANGLE (1U << 3)
#define HID_MASK_L1 (1U << 4)
#define HID_MASK_R1 (1U << 5)
#define HID_MASK_L2 (1U << 6)
#define HID_MASK_R2 (1U << 7)
#define HID_MASK_SELECT (1U << 8)
#define HID_MASK_START (1U << 9)
#define HID_MASK_L3 (1U << 10)
#define HID_MASK_R3 (1U << 11)
#define HID_MASK_PS (1U << 12)
#define HID_MASK_TP (1U << 13)
// Switch analog sticks only report 8 bits
#define HID_JOYSTICK_MIN 0x00
#define HID_JOYSTICK_MID 0x80
#define HID_JOYSTICK_MAX 0xFF
struct TouchpadXY {
uint8_t counter : 7;
uint8_t unpressed : 1;
// 12 bit X, followed by 12 bit Y
uint8_t data[3];
void set_x(uint16_t x) {
data[0] = x & 0xff;
data[1] = (data[1] & 0xf0) | ((x >> 8) & 0xf);
}
void set_y(uint16_t y) {
data[1] = (data[1] & 0x0f) | ((y & 0xf) << 4);
data[2] = y >> 4;
return;
}
};
struct TouchpadData {
TouchpadXY p1;
TouchpadXY p2;
};
typedef struct __attribute__((packed)) {
uint8_t report_id;
uint8_t left_stick_x;
uint8_t left_stick_y;
uint8_t right_stick_x;
uint8_t right_stick_y;
// 4 bits for the d-pad.
uint32_t dpad : 4;
// 14 bits for buttons.
uint32_t button_west : 1;
uint32_t button_south : 1;
uint32_t button_east : 1;
uint32_t button_north : 1;
uint32_t button_l1 : 1;
uint32_t button_r1 : 1;
uint32_t button_l2 : 1;
uint32_t button_r2 : 1;
uint32_t button_select : 1;
uint32_t button_start : 1;
uint32_t button_l3 : 1;
uint32_t button_r3 : 1;
uint32_t button_home : 1;
uint32_t button_touchpad : 1;
// 6 bit report counter.
uint32_t report_counter : 6;
uint32_t left_trigger : 8;
uint32_t right_trigger : 8;
uint32_t padding : 24;
uint8_t mystery[22];
TouchpadData touchpad_data;
uint8_t mystery_2[21];
} PS4Report;
static const uint8_t ps4_string_language[] = { 0x09, 0x04 };
static const uint8_t ps4_string_manufacturer[] = "Open Stick Community";
static const uint8_t ps4_string_product[] = "GP2040-CE (PS4)";
static const uint8_t ps4_string_version[] = "1.0";
static const uint8_t *ps4_string_descriptors[] =
{
ps4_string_language,
ps4_string_manufacturer,
ps4_string_product,
ps4_string_version
};
static const uint8_t ps4_device_descriptor[] =
{
18, // bLength
1, // bDescriptorType
0x00, 0x02, // bcdUSB
0, // bDeviceClass
0, // bDeviceSubClass
0, // bDeviceProtocol
ENDPOINT0_SIZE, // bMaxPacketSize0
LSB(PS4_VENDOR_ID), MSB(PS4_VENDOR_ID), // idVendor
LSB(PS4_PRODUCT_ID), MSB(PS4_PRODUCT_ID), // idProduct
0x00, 0x01, // bcdDevice
1, // iManufacturer
2, // iProduct
0, // iSerialNumber
1 // bNumConfigurations
};
static const uint8_t ps4_report_descriptor[] =
{
0x05, 0x01, // Usage Page (Generic Desktop Ctrls)
0x09, 0x05, // Usage (Game Pad)
0xA1, 0x01, // Collection (Application)
0x85, 0x01, // Report ID (1)
0x09, 0x30, // Usage (X)
0x09, 0x31, // Usage (Y)
0x09, 0x32, // Usage (Z)
0x09, 0x35, // Usage (Rz)
0x15, 0x00, // Logical Minimum (0)
0x26, 0xFF, 0x00, // Logical Maximum (255)
0x75, 0x08, // Report Size (8)
0x95, 0x04, // Report Count (4)
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x09, 0x39, // Usage (Hat switch)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x07, // Logical Maximum (7)
0x35, 0x00, // Physical Minimum (0)
0x46, 0x3B, 0x01, // Physical Maximum (315)
0x65, 0x14, // Unit (System: English Rotation, Length: Centimeter)
0x75, 0x04, // Report Size (4)
0x95, 0x01, // Report Count (1)
0x81, 0x42, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,Null State)
0x65, 0x00, // Unit (None)
0x05, 0x09, // Usage Page (Button)
0x19, 0x01, // Usage Minimum (0x01)
0x29, 0x0E, // Usage Maximum (0x0E)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1)
0x75, 0x01, // Report Size (1)
0x95, 0x0E, // Report Count (14)
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x06, 0x00, 0xFF, // Usage Page (Vendor Defined 0xFF00)
0x09, 0x20, // Usage (0x20)
0x75, 0x06, // Report Size (6)
0x95, 0x01, // Report Count (1)
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x05, 0x01, // Usage Page (Generic Desktop Ctrls)
0x09, 0x33, // Usage (Rx)
0x09, 0x34, // Usage (Ry)
0x15, 0x00, // Logical Minimum (0)
0x26, 0xFF, 0x00, // Logical Maximum (255)
0x75, 0x08, // Report Size (8)
0x95, 0x02, // Report Count (2)
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x06, 0x00, 0xFF, // Usage Page (Vendor Defined 0xFF00)
0x09, 0x21, // Usage (0x21)
0x95, 0x36, // Report Count (54)
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x85, 0x05, // Report ID (5)
0x09, 0x22, // Usage (0x22)
0x95, 0x1F, // Report Count (31)
0x91, 0x02, // Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x03, // Report ID (3)
0x0A, 0x21, 0x27, // Usage (0x2721)
0x95, 0x2F, // Report Count (47)
0xB1, 0x02, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0, // End Collection
0x06, 0xF0, 0xFF, // Usage Page (Vendor Defined 0xFFF0)
0x09, 0x40, // Usage (0x40)
0xA1, 0x01, // Collection (Application)
0x85, 0xF0, // Report ID (-16) AUTH F0
0x09, 0x47, // Usage (0x47)
0x95, 0x3F, // Report Count (63)
0xB1, 0x02, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xF1, // Report ID (-15) AUTH F1
0x09, 0x48, // Usage (0x48)
0x95, 0x3F, // Report Count (63)
0xB1, 0x02, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xF2, // Report ID (-14) AUTH F2
0x09, 0x49, // Usage (0x49)
0x95, 0x0F, // Report Count (15)
0xB1, 0x02, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xF3, // Report ID (-13) Auth F3 (Reset)
0x0A, 0x01, 0x47, // Usage (0x4701)
0x95, 0x07, // Report Count (7)
0xB1, 0x02, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0, // End Collection
};
static const uint8_t ps4_hid_descriptor[] =
{
0x09, // bLength
0x21, // bDescriptorType (HID)
0x11, 0x01, // bcdHID 1.11
0x00, // bCountryCode
0x01, // bNumDescriptors
0x22, // bDescriptorType[0] (HID)
sizeof(ps4_report_descriptor), 0x00, // wDescriptorLength[0] 90
};
#define CONFIG1_DESC_SIZE (9+9+9+7)
static const uint8_t ps4_configuration_descriptor[] =
{
// configuration descriptor, USB spec 9.6.3, page 264-266, Table 9-10
9, // bLength;
2, // bDescriptorType;
LSB(CONFIG1_DESC_SIZE), // wTotalLength
MSB(CONFIG1_DESC_SIZE),
1, // bNumInterfaces
1, // bConfigurationValue
0, // iConfiguration
0x80, // bmAttributes
50, // bMaxPower
// interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
9, // bLength
4, // bDescriptorType
GAMEPAD_INTERFACE, // bInterfaceNumber
0, // bAlternateSetting
1, // bNumEndpoints
0x03, // bInterfaceClass (0x03 = HID)
0x00, // bInterfaceSubClass (0x00 = No Boot)
0x00, // bInterfaceProtocol (0x00 = No Protocol)
0, // iInterface
// HID interface descriptor, HID 1.11 spec, section 6.2.1
9, // bLength
0x21, // bDescriptorType
0x11, 0x01, // bcdHID
0, // bCountryCode
1, // bNumDescriptors
0x22, // bDescriptorType
sizeof(ps4_report_descriptor), // wDescriptorLength
0,
// endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
7, // bLength
5, // bDescriptorType
GAMEPAD_ENDPOINT | 0x80, // bEndpointAddress
0x03, // bmAttributes (0x03=intr)
GAMEPAD_SIZE, 0, // wMaxPacketSize
1 // bInterval (1 ms)
};

View File

@@ -1,27 +1,27 @@
/* This can be enabled lated when we use SNTP */
#undef MBEDTLS_HAVE_TIME_DATE
#define MBEDTLS_CHECK_PARAMS
#define MBEDTLS_CHECK_PARAMS_ASSERT
#define MBEDTLS_ENTROPY_HARDWARE_ALT
#define MBEDTLS_AES_ROM_TABLES
#define MBEDTLS_AES_FEWER_TABLES
#define MBEDTLS_CAMELLIA_SMALL_MEMORY
#define MBEDTLS_CHECK_RETURN_WARNING
#undef MBEDTLS_FS_IO
#define MBEDTLS_NO_PLATFORM_ENTROPY
#define MBEDTLS_PSA_CRYPTO_CLIENT
#define MBEDTLS_PSA_CRYPTO_DRIVERS
#define MBEDTLS_SHA256_C
#define MBEDTLS_RSA_C
#define MBEDTLS_X509_RSASSA_PSS_SUPPORT
#define MBEDTLS_PKCS1_V21
#define MBEDTLS_BIGNUM_C
#define MBEDTLS_MD_C
#define MBEDTLS_SSL_ASYNC_PRIVATE
#define MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH
#define MBEDTLS_USE_PSA_CRYPTO
#undef MBEDTLS_NET_C
#undef MBEDTLS_PSA_CRYPTO_STORAGE_C
#undef MBEDTLS_PSA_ITS_FILE_C
#undef MBEDTLS_TIMING_C
/* This can be enabled lated when we use SNTP */
#undef MBEDTLS_HAVE_TIME_DATE
#define MBEDTLS_CHECK_PARAMS
#define MBEDTLS_CHECK_PARAMS_ASSERT
#define MBEDTLS_ENTROPY_HARDWARE_ALT
#define MBEDTLS_AES_ROM_TABLES
#define MBEDTLS_AES_FEWER_TABLES
#define MBEDTLS_CAMELLIA_SMALL_MEMORY
#define MBEDTLS_CHECK_RETURN_WARNING
#undef MBEDTLS_FS_IO
#define MBEDTLS_NO_PLATFORM_ENTROPY
#define MBEDTLS_PSA_CRYPTO_CLIENT
#define MBEDTLS_PSA_CRYPTO_DRIVERS
#define MBEDTLS_SHA256_C
#define MBEDTLS_RSA_C
#define MBEDTLS_X509_RSASSA_PSS_SUPPORT
#define MBEDTLS_PKCS1_V21
#define MBEDTLS_BIGNUM_C
#define MBEDTLS_MD_C
#define MBEDTLS_SSL_ASYNC_PRIVATE
#define MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH
#define MBEDTLS_USE_PSA_CRYPTO
#undef MBEDTLS_NET_C
#undef MBEDTLS_PSA_CRYPTO_STORAGE_C
#undef MBEDTLS_PSA_ITS_FILE_C
#undef MBEDTLS_TIMING_C

View File

@@ -1,114 +1,114 @@
// -------------------------------------------------- //
// This file is autogenerated by pioasm; do not edit! //
// -------------------------------------------------- //
#pragma once
#if !PICO_NO_HARDWARE
#include "hardware/pio.h"
#endif
// ------ //
// ws2812 //
// ------ //
#define ws2812_wrap_target 0
#define ws2812_wrap 3
#define ws2812_T1 2
#define ws2812_T2 5
#define ws2812_T3 3
static const uint16_t ws2812_program_instructions[] = {
// .wrap_target
0x6221, // 0: out x, 1 side 0 [2]
0x1123, // 1: jmp !x, 3 side 1 [1]
0x1400, // 2: jmp 0 side 1 [4]
0xa442, // 3: nop side 0 [4]
// .wrap
};
#if !PICO_NO_HARDWARE
static const struct pio_program ws2812_program = {
.instructions = ws2812_program_instructions,
.length = 4,
.origin = -1,
};
static inline pio_sm_config ws2812_program_get_default_config(uint offset) {
pio_sm_config c = pio_get_default_sm_config();
sm_config_set_wrap(&c, offset + ws2812_wrap_target, offset + ws2812_wrap);
sm_config_set_sideset(&c, 1, false, false);
return c;
}
#include "hardware/clocks.h"
static inline void ws2812_program_init(PIO pio, uint sm, uint offset, uint pin, float freq, bool rgbw) {
pio_gpio_init(pio, pin);
pio_sm_set_consecutive_pindirs(pio, sm, pin, 1, true);
pio_sm_config c = ws2812_program_get_default_config(offset);
sm_config_set_sideset_pins(&c, pin);
sm_config_set_out_shift(&c, false, true, rgbw ? 32 : 24);
sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_TX);
int cycles_per_bit = ws2812_T1 + ws2812_T2 + ws2812_T3;
float div = clock_get_hz(clk_sys) / (freq * cycles_per_bit);
sm_config_set_clkdiv(&c, div);
pio_sm_init(pio, sm, offset, &c);
pio_sm_set_enabled(pio, sm, true);
}
#endif
// --------------- //
// ws2812_parallel //
// --------------- //
#define ws2812_parallel_wrap_target 0
#define ws2812_parallel_wrap 3
#define ws2812_parallel_T1 2
#define ws2812_parallel_T2 5
#define ws2812_parallel_T3 3
static const uint16_t ws2812_parallel_program_instructions[] = {
// .wrap_target
0x6020, // 0: out x, 32
0xa10b, // 1: mov pins, !null [1]
0xa401, // 2: mov pins, x [4]
0xa103, // 3: mov pins, null [1]
// .wrap
};
#if !PICO_NO_HARDWARE
static const struct pio_program ws2812_parallel_program = {
.instructions = ws2812_parallel_program_instructions,
.length = 4,
.origin = -1,
};
static inline pio_sm_config ws2812_parallel_program_get_default_config(uint offset) {
pio_sm_config c = pio_get_default_sm_config();
sm_config_set_wrap(&c, offset + ws2812_parallel_wrap_target, offset + ws2812_parallel_wrap);
return c;
}
#include "hardware/clocks.h"
static inline void ws2812_parallel_program_init(PIO pio, uint sm, uint offset, uint pin_base, uint pin_count, float freq) {
for(uint i=pin_base; i<pin_base+pin_count; i++) {
pio_gpio_init(pio, i);
}
pio_sm_set_consecutive_pindirs(pio, sm, pin_base, pin_count, true);
pio_sm_config c = ws2812_parallel_program_get_default_config(offset);
sm_config_set_out_shift(&c, true, true, 32);
sm_config_set_out_pins(&c, pin_base, pin_count);
sm_config_set_set_pins(&c, pin_base, pin_count);
sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_TX);
int cycles_per_bit = ws2812_parallel_T1 + ws2812_parallel_T2 + ws2812_parallel_T3;
float div = clock_get_hz(clk_sys) / (freq * cycles_per_bit);
sm_config_set_clkdiv(&c, div);
pio_sm_init(pio, sm, offset, &c);
pio_sm_set_enabled(pio, sm, true);
}
#endif
// -------------------------------------------------- //
// This file is autogenerated by pioasm; do not edit! //
// -------------------------------------------------- //
#pragma once
#if !PICO_NO_HARDWARE
#include "hardware/pio.h"
#endif
// ------ //
// ws2812 //
// ------ //
#define ws2812_wrap_target 0
#define ws2812_wrap 3
#define ws2812_T1 2
#define ws2812_T2 5
#define ws2812_T3 3
static const uint16_t ws2812_program_instructions[] = {
// .wrap_target
0x6221, // 0: out x, 1 side 0 [2]
0x1123, // 1: jmp !x, 3 side 1 [1]
0x1400, // 2: jmp 0 side 1 [4]
0xa442, // 3: nop side 0 [4]
// .wrap
};
#if !PICO_NO_HARDWARE
static const struct pio_program ws2812_program = {
.instructions = ws2812_program_instructions,
.length = 4,
.origin = -1,
};
static inline pio_sm_config ws2812_program_get_default_config(uint offset) {
pio_sm_config c = pio_get_default_sm_config();
sm_config_set_wrap(&c, offset + ws2812_wrap_target, offset + ws2812_wrap);
sm_config_set_sideset(&c, 1, false, false);
return c;
}
#include "hardware/clocks.h"
static inline void ws2812_program_init(PIO pio, uint sm, uint offset, uint pin, float freq, bool rgbw) {
pio_gpio_init(pio, pin);
pio_sm_set_consecutive_pindirs(pio, sm, pin, 1, true);
pio_sm_config c = ws2812_program_get_default_config(offset);
sm_config_set_sideset_pins(&c, pin);
sm_config_set_out_shift(&c, false, true, rgbw ? 32 : 24);
sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_TX);
int cycles_per_bit = ws2812_T1 + ws2812_T2 + ws2812_T3;
float div = clock_get_hz(clk_sys) / (freq * cycles_per_bit);
sm_config_set_clkdiv(&c, div);
pio_sm_init(pio, sm, offset, &c);
pio_sm_set_enabled(pio, sm, true);
}
#endif
// --------------- //
// ws2812_parallel //
// --------------- //
#define ws2812_parallel_wrap_target 0
#define ws2812_parallel_wrap 3
#define ws2812_parallel_T1 2
#define ws2812_parallel_T2 5
#define ws2812_parallel_T3 3
static const uint16_t ws2812_parallel_program_instructions[] = {
// .wrap_target
0x6020, // 0: out x, 32
0xa10b, // 1: mov pins, !null [1]
0xa401, // 2: mov pins, x [4]
0xa103, // 3: mov pins, null [1]
// .wrap
};
#if !PICO_NO_HARDWARE
static const struct pio_program ws2812_parallel_program = {
.instructions = ws2812_parallel_program_instructions,
.length = 4,
.origin = -1,
};
static inline pio_sm_config ws2812_parallel_program_get_default_config(uint offset) {
pio_sm_config c = pio_get_default_sm_config();
sm_config_set_wrap(&c, offset + ws2812_parallel_wrap_target, offset + ws2812_parallel_wrap);
return c;
}
#include "hardware/clocks.h"
static inline void ws2812_parallel_program_init(PIO pio, uint sm, uint offset, uint pin_base, uint pin_count, float freq) {
for(uint i=pin_base; i<pin_base+pin_count; i++) {
pio_gpio_init(pio, i);
}
pio_sm_set_consecutive_pindirs(pio, sm, pin_base, pin_count, true);
pio_sm_config c = ws2812_parallel_program_get_default_config(offset);
sm_config_set_out_shift(&c, true, true, 32);
sm_config_set_out_pins(&c, pin_base, pin_count);
sm_config_set_set_pins(&c, pin_base, pin_count);
sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_TX);
int cycles_per_bit = ws2812_parallel_T1 + ws2812_parallel_T2 + ws2812_parallel_T3;
float div = clock_get_hz(clk_sys) / (freq * cycles_per_bit);
sm_config_set_clkdiv(&c, div);
pio_sm_init(pio, sm, offset, &c);
pio_sm_set_enabled(pio, sm, true);
}
#endif

View File

@@ -1,217 +1,217 @@
/*
* SPDX-License-Identifier: MIT
* SPDX-FileCopyrightText: Copyright (c) 2021 Jason Skuby (mytechtoybox.com)
*/
#include "ps4_driver.h"
#include "CRC32.h"
#include "mbedtls/error.h"
#include "mbedtls/rsa.h"
#include "mbedtls/sha256.h"
#include <random>
uint8_t ps4_endpoint_in = 0;
uint8_t ps4_endpoint_out = 0;
uint8_t ps4_out_buffer[PS4_OUT_SIZE] = {};
// Alternative version
static constexpr uint8_t output_0x03[] = {
0x21, 0x27, 0x04, 0xcf, 0x00, 0x2c, 0x56,
0x08, 0x00, 0x3d, 0x00, 0xe8, 0x03, 0x04, 0x00,
0xff, 0x7f, 0x0d, 0x0d, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
// Passinglink version
/*static constexpr uint8_t output_0x03[] = {
0x21, 0x27, 0x4, 0x40, 0x7, 0x2c, 0x56, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0xd, 0xd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
};*/
// Nonce Page Size: 0x38 (56)
// Response Page Size: 0x38 (56)
static constexpr uint8_t output_0xf3[] = { 0x0, 0x38, 0x38, 0, 0, 0, 0 };
static uint8_t cur_nonce_id = 1;
// debug
static int rss_error = 0;
static uint8_t send_nonce_part = 0;
struct PS4Key {
unsigned char serial[16];
unsigned char signature[256];
struct mbedtls_rsa_context* rsa_context;
};
struct SignaturePart {
size_t length;
size_t (*function)(uint8_t * buf, size_t offset, const void* arg, size_t expected_size);
const void* arg;
};
ssize_t get_ps4_report(uint8_t report_id, uint8_t * buf, uint16_t reqlen)
{
uint8_t data[64] = {};
uint32_t crc32;
ps4_out_buffer[0] = report_id;
switch(report_id) {
// Not sure on 0x03? maybe a controller qualifier
case PS4AuthReport::PS4_UNKNOWN_0X03:
if (reqlen != sizeof(output_0x03)) {
return -1;
}
memcpy(buf, output_0x03, reqlen);
return reqlen;
// Use our private RSA key to sign the nonce and return chunks
case PS4AuthReport::PS4_GET_SIGNATURE_NONCE:
// We send 56 byte chunks back to the PS4, we've already calculated these
data[0] = 0xF1;
data[1] = cur_nonce_id; // nonce_id
data[2] = send_nonce_part; // next_part
data[3] = 0;
// 56 byte chunks
memcpy(&data[4], &PS4Data::getInstance().ps4_auth_buffer[send_nonce_part*56], 56);
// calculate the CRC32 of the buffer and write it back
crc32 = CRC32::calculate(data, 60);
memcpy(&data[60], &crc32, sizeof(uint32_t));
memcpy(buf, &data[1], 63); // move data over to buffer
if ( (++send_nonce_part) == 19 ) {
PS4Data::getInstance().ps4State = PS4State::no_nonce;
PS4Data::getInstance().authsent = true;
send_nonce_part = 0;
}
return 63;
// Are we ready to sign?
case PS4AuthReport::PS4_GET_SIGNING_STATE:
data[0] = 0xF2;
data[1] = cur_nonce_id;
data[2] = PS4Data::getInstance().ps4State == PS4State::signed_nonce_ready ? 0 : 16; // 0 means auth is ready, 16 means we're still signing
memset(&data[3], 0, 9);
crc32 = CRC32::calculate(data, 12);
memcpy(&data[12], &crc32, sizeof(uint32_t));
memcpy(buf, &data[1], 15); // move data over to buffer
return 15;
case PS4AuthReport::PS4_RESET_AUTH: // Reset the Authentication
if (reqlen != sizeof(output_0xf3)) {
return -1;
}
memcpy(buf, output_0xf3, reqlen);
PS4Data::getInstance().ps4State = PS4State::no_nonce;
return reqlen;
default:
break;
};
return -1;
}
void set_ps4_report(uint8_t report_id, uint8_t const * data, uint16_t reqlen)
{
uint8_t nonce_id;
uint8_t nonce_page;
uint32_t crc32;
uint8_t buffer[64];
uint8_t nonce[56]; // max nonce data
uint16_t noncelen;
uint16_t buflen;
if (report_id == PS4AuthReport::PS4_SET_AUTH_PAYLOAD) {
if (reqlen != 63 ) {
return;
}
// Setup CRC32 buffer
buffer[0] = report_id;
memcpy(&buffer[1], data, reqlen);
buflen = reqlen + 1;
nonce_id = data[0];
nonce_page = data[1];
// data[2] is zero padding
crc32 = CRC32::calculate(buffer, buflen-sizeof(uint32_t));
if ( crc32 != *((unsigned int*)&buffer[buflen-sizeof(uint32_t)])) {
return; // CRC32 failed on set report
}
// 256 byte nonce, with 56 byte packets leaves 24 extra bytes on the last packet?
if ( nonce_page == 4 ) {
// Copy/append data from buffer[4:64-28] into our nonce
noncelen = 32; // from 4 to 64 - 24 - 4
} else {
// Copy/append data from buffer[4:64-4] into our nonce
noncelen = 56;
// from 4 to 64 - 4
}
memcpy(nonce, &buffer[4], noncelen);
save_nonce(nonce_id, nonce_page, nonce, noncelen);
}
}
void save_nonce(uint8_t nonce_id, uint8_t nonce_page, uint8_t * buffer, uint16_t buflen) {
if ( nonce_page != 0 && nonce_id != cur_nonce_id ) {
PS4Data::getInstance().ps4State = PS4State::no_nonce;
return; // setting nonce with mismatched id
}
memcpy(&PS4Data::getInstance().nonce_buffer[nonce_page*56], buffer, buflen);
if ( nonce_page == 4 ) {
PS4Data::getInstance().ps4State = PS4State::nonce_ready;
} else if ( nonce_page == 0 ) {
cur_nonce_id = nonce_id;
PS4Data::getInstance().ps4State = PS4State::receiving_nonce;
}
}
void receive_ps4_report(void)
{
if (
tud_ready() &&
(ps4_endpoint_out != 0) && (!usbd_edpt_busy(0, ps4_endpoint_out)))
{
usbd_edpt_claim(0, ps4_endpoint_out); // Take control of OUT endpoint
usbd_edpt_xfer(0, ps4_endpoint_out, ps4_out_buffer, PS4_OUT_SIZE); // Retrieve report buffer
usbd_edpt_release(0, ps4_endpoint_out); // Release control of OUT endpoint
}
}
bool send_ps4_report(void *report, uint8_t report_size)
{
bool sent = false;
if (
tud_ready() && // Is the device ready?
(ps4_endpoint_in != 0) && (!usbd_edpt_busy(0, ps4_endpoint_in)) // Is the IN endpoint available?
)
{
usbd_edpt_claim(0, ps4_endpoint_in); // Take control of IN endpoint
usbd_edpt_xfer(0, ps4_endpoint_in, (uint8_t *)report, report_size); // Send report buffer
usbd_edpt_release(0, ps4_endpoint_in); // Release control of IN endpoint
sent = true;
}
return sent;
}
const usbd_class_driver_t ps4_driver =
{
#if CFG_TUSB_DEBUG >= 2
.name = "PS4",
#endif
.init = hidd_init,
.reset = hidd_reset,
.open = hidd_open,
.control_xfer_cb = hidd_control_xfer_cb,
.xfer_cb = hidd_xfer_cb,
.sof = NULL};
/*
* SPDX-License-Identifier: MIT
* SPDX-FileCopyrightText: Copyright (c) 2021 Jason Skuby (mytechtoybox.com)
*/
#include "ps4_driver.h"
#include "CRC32.h"
#include "mbedtls/error.h"
#include "mbedtls/rsa.h"
#include "mbedtls/sha256.h"
#include <random>
uint8_t ps4_endpoint_in = 0;
uint8_t ps4_endpoint_out = 0;
uint8_t ps4_out_buffer[PS4_OUT_SIZE] = {};
// Alternative version
static constexpr uint8_t output_0x03[] = {
0x21, 0x27, 0x04, 0xcf, 0x00, 0x2c, 0x56,
0x08, 0x00, 0x3d, 0x00, 0xe8, 0x03, 0x04, 0x00,
0xff, 0x7f, 0x0d, 0x0d, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
// Passinglink version
/*static constexpr uint8_t output_0x03[] = {
0x21, 0x27, 0x4, 0x40, 0x7, 0x2c, 0x56, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0xd, 0xd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
};*/
// Nonce Page Size: 0x38 (56)
// Response Page Size: 0x38 (56)
static constexpr uint8_t output_0xf3[] = { 0x0, 0x38, 0x38, 0, 0, 0, 0 };
static uint8_t cur_nonce_id = 1;
// debug
static int rss_error = 0;
static uint8_t send_nonce_part = 0;
struct PS4Key {
unsigned char serial[16];
unsigned char signature[256];
struct mbedtls_rsa_context* rsa_context;
};
struct SignaturePart {
size_t length;
size_t (*function)(uint8_t * buf, size_t offset, const void* arg, size_t expected_size);
const void* arg;
};
ssize_t get_ps4_report(uint8_t report_id, uint8_t * buf, uint16_t reqlen)
{
uint8_t data[64] = {};
uint32_t crc32;
ps4_out_buffer[0] = report_id;
switch(report_id) {
// Not sure on 0x03? maybe a controller qualifier
case PS4AuthReport::PS4_UNKNOWN_0X03:
if (reqlen != sizeof(output_0x03)) {
return -1;
}
memcpy(buf, output_0x03, reqlen);
return reqlen;
// Use our private RSA key to sign the nonce and return chunks
case PS4AuthReport::PS4_GET_SIGNATURE_NONCE:
// We send 56 byte chunks back to the PS4, we've already calculated these
data[0] = 0xF1;
data[1] = cur_nonce_id; // nonce_id
data[2] = send_nonce_part; // next_part
data[3] = 0;
// 56 byte chunks
memcpy(&data[4], &PS4Data::getInstance().ps4_auth_buffer[send_nonce_part*56], 56);
// calculate the CRC32 of the buffer and write it back
crc32 = CRC32::calculate(data, 60);
memcpy(&data[60], &crc32, sizeof(uint32_t));
memcpy(buf, &data[1], 63); // move data over to buffer
if ( (++send_nonce_part) == 19 ) {
PS4Data::getInstance().ps4State = PS4State::no_nonce;
PS4Data::getInstance().authsent = true;
send_nonce_part = 0;
}
return 63;
// Are we ready to sign?
case PS4AuthReport::PS4_GET_SIGNING_STATE:
data[0] = 0xF2;
data[1] = cur_nonce_id;
data[2] = PS4Data::getInstance().ps4State == PS4State::signed_nonce_ready ? 0 : 16; // 0 means auth is ready, 16 means we're still signing
memset(&data[3], 0, 9);
crc32 = CRC32::calculate(data, 12);
memcpy(&data[12], &crc32, sizeof(uint32_t));
memcpy(buf, &data[1], 15); // move data over to buffer
return 15;
case PS4AuthReport::PS4_RESET_AUTH: // Reset the Authentication
if (reqlen != sizeof(output_0xf3)) {
return -1;
}
memcpy(buf, output_0xf3, reqlen);
PS4Data::getInstance().ps4State = PS4State::no_nonce;
return reqlen;
default:
break;
};
return -1;
}
void set_ps4_report(uint8_t report_id, uint8_t const * data, uint16_t reqlen)
{
uint8_t nonce_id;
uint8_t nonce_page;
uint32_t crc32;
uint8_t buffer[64];
uint8_t nonce[56]; // max nonce data
uint16_t noncelen;
uint16_t buflen;
if (report_id == PS4AuthReport::PS4_SET_AUTH_PAYLOAD) {
if (reqlen != 63 ) {
return;
}
// Setup CRC32 buffer
buffer[0] = report_id;
memcpy(&buffer[1], data, reqlen);
buflen = reqlen + 1;
nonce_id = data[0];
nonce_page = data[1];
// data[2] is zero padding
crc32 = CRC32::calculate(buffer, buflen-sizeof(uint32_t));
if ( crc32 != *((unsigned int*)&buffer[buflen-sizeof(uint32_t)])) {
return; // CRC32 failed on set report
}
// 256 byte nonce, with 56 byte packets leaves 24 extra bytes on the last packet?
if ( nonce_page == 4 ) {
// Copy/append data from buffer[4:64-28] into our nonce
noncelen = 32; // from 4 to 64 - 24 - 4
} else {
// Copy/append data from buffer[4:64-4] into our nonce
noncelen = 56;
// from 4 to 64 - 4
}
memcpy(nonce, &buffer[4], noncelen);
save_nonce(nonce_id, nonce_page, nonce, noncelen);
}
}
void save_nonce(uint8_t nonce_id, uint8_t nonce_page, uint8_t * buffer, uint16_t buflen) {
if ( nonce_page != 0 && nonce_id != cur_nonce_id ) {
PS4Data::getInstance().ps4State = PS4State::no_nonce;
return; // setting nonce with mismatched id
}
memcpy(&PS4Data::getInstance().nonce_buffer[nonce_page*56], buffer, buflen);
if ( nonce_page == 4 ) {
PS4Data::getInstance().ps4State = PS4State::nonce_ready;
} else if ( nonce_page == 0 ) {
cur_nonce_id = nonce_id;
PS4Data::getInstance().ps4State = PS4State::receiving_nonce;
}
}
void receive_ps4_report(void)
{
if (
tud_ready() &&
(ps4_endpoint_out != 0) && (!usbd_edpt_busy(0, ps4_endpoint_out)))
{
usbd_edpt_claim(0, ps4_endpoint_out); // Take control of OUT endpoint
usbd_edpt_xfer(0, ps4_endpoint_out, ps4_out_buffer, PS4_OUT_SIZE); // Retrieve report buffer
usbd_edpt_release(0, ps4_endpoint_out); // Release control of OUT endpoint
}
}
bool send_ps4_report(void *report, uint8_t report_size)
{
bool sent = false;
if (
tud_ready() && // Is the device ready?
(ps4_endpoint_in != 0) && (!usbd_edpt_busy(0, ps4_endpoint_in)) // Is the IN endpoint available?
)
{
usbd_edpt_claim(0, ps4_endpoint_in); // Take control of IN endpoint
usbd_edpt_xfer(0, ps4_endpoint_in, (uint8_t *)report, report_size); // Send report buffer
usbd_edpt_release(0, ps4_endpoint_in); // Release control of IN endpoint
sent = true;
}
return sent;
}
const usbd_class_driver_t ps4_driver =
{
#if CFG_TUSB_DEBUG >= 2
.name = "PS4",
#endif
.init = hidd_init,
.reset = hidd_reset,
.open = hidd_open,
.control_xfer_cb = hidd_control_xfer_cb,
.xfer_cb = hidd_xfer_cb,
.sof = NULL};

View File

@@ -1,73 +1,73 @@
/*
* SPDX-License-Identifier: MIT
* SPDX-FileCopyrightText: Copyright (c) 2021 Jason Skuby (mytechtoybox.com)
*/
#pragma once
#include "tusb.h"
#include "device/usbd_pvt.h"
#include "gamepad/descriptors/PS4Descriptors.h"
#define PS4_OUT_SIZE 64
typedef enum
{
PS4_UNKNOWN_0X03 = 0x03, // Unknown (PS4 Report 0x03)
PS4_SET_AUTH_PAYLOAD = 0xF0, // Set Auth Payload
PS4_GET_SIGNATURE_NONCE = 0xF1, // Get Signature Nonce
PS4_GET_SIGNING_STATE = 0xF2, // Get Signing State
PS4_RESET_AUTH = 0xF3 // Unknown (PS4 Report 0xF3)
} PS4AuthReport;
// USB endpoint state vars
extern const usbd_class_driver_t ps4_driver;
ssize_t get_ps4_report(uint8_t report_id, uint8_t * buf, uint16_t reqlen);
void set_ps4_report(uint8_t report_id, uint8_t const * buf, uint16_t reqlen);
void receive_ps4_report(void);
bool send_ps4_report(void *report, uint8_t report_size);
void save_nonce(uint8_t nonce_id, uint8_t nonce_page, uint8_t * data, uint16_t size);
typedef enum {
no_nonce = 0,
receiving_nonce = 1,
nonce_ready = 2,
signed_nonce_ready = 3
} PS4State;
// Storage manager for board, LED options, and thread-safe settings
class PS4Data {
public:
PS4Data(PS4Data const&) = delete;
void operator=(PS4Data const&) = delete;
static PS4Data& getInstance() // Thread-safe storage ensures cross-thread talk
{
static PS4Data instance;
return instance;
}
PS4State ps4State;
bool authsent;
uint8_t nonce_buffer[256];
// Send back in 56 byte chunks:
// 256 byte - nonce signature
// 16 byte - ps4 serial
// 256 byte - RSA N
// 256 byte - RSA E
// 256 byte - ps4 signature
// 24 byte - zero padding
// buffer = 256 + 16 + 256 + 256 + 256 + 24
// == 1064 bytes (almost 1 kb)
uint8_t ps4_auth_buffer[1064];
private:
PS4Data() {
ps4State = PS4State::no_nonce;
authsent = false;
memset(nonce_buffer, 0, 256);
memset(ps4_auth_buffer, 0, 1064);
}
};
/*
* SPDX-License-Identifier: MIT
* SPDX-FileCopyrightText: Copyright (c) 2021 Jason Skuby (mytechtoybox.com)
*/
#pragma once
#include "tusb.h"
#include "device/usbd_pvt.h"
#include "gamepad/descriptors/PS4Descriptors.h"
#define PS4_OUT_SIZE 64
typedef enum
{
PS4_UNKNOWN_0X03 = 0x03, // Unknown (PS4 Report 0x03)
PS4_SET_AUTH_PAYLOAD = 0xF0, // Set Auth Payload
PS4_GET_SIGNATURE_NONCE = 0xF1, // Get Signature Nonce
PS4_GET_SIGNING_STATE = 0xF2, // Get Signing State
PS4_RESET_AUTH = 0xF3 // Unknown (PS4 Report 0xF3)
} PS4AuthReport;
// USB endpoint state vars
extern const usbd_class_driver_t ps4_driver;
ssize_t get_ps4_report(uint8_t report_id, uint8_t * buf, uint16_t reqlen);
void set_ps4_report(uint8_t report_id, uint8_t const * buf, uint16_t reqlen);
void receive_ps4_report(void);
bool send_ps4_report(void *report, uint8_t report_size);
void save_nonce(uint8_t nonce_id, uint8_t nonce_page, uint8_t * data, uint16_t size);
typedef enum {
no_nonce = 0,
receiving_nonce = 1,
nonce_ready = 2,
signed_nonce_ready = 3
} PS4State;
// Storage manager for board, LED options, and thread-safe settings
class PS4Data {
public:
PS4Data(PS4Data const&) = delete;
void operator=(PS4Data const&) = delete;
static PS4Data& getInstance() // Thread-safe storage ensures cross-thread talk
{
static PS4Data instance;
return instance;
}
PS4State ps4State;
bool authsent;
uint8_t nonce_buffer[256];
// Send back in 56 byte chunks:
// 256 byte - nonce signature
// 16 byte - ps4 serial
// 256 byte - RSA N
// 256 byte - RSA E
// 256 byte - ps4 signature
// 24 byte - zero padding
// buffer = 256 + 16 + 256 + 256 + 256 + 24
// == 1064 bytes (almost 1 kb)
uint8_t ps4_auth_buffer[1064];
private:
PS4Data() {
ps4State = PS4State::no_nonce;
authsent = false;
memset(nonce_buffer, 0, 256);
memset(ps4_auth_buffer, 0, 1064);
}
};

View File

@@ -1,117 +1,117 @@
/*
* SPDX-License-Identifier: MIT
* SPDX-FileCopyrightText: Copyright (c) 2021 Jason Skuby (mytechtoybox.com)
*/
#include "addons/ps4mode.h"
#include "helper.h"
#include "config.pb.h"
#include "ps4_driver.h"
#include "mbedtls/error.h"
#include "mbedtls/rsa.h"
#include "mbedtls/sha256.h"
bool PS4ModeAddon::available() {
const PS4Options& options = Storage::getInstance().getAddonOptions().ps4Options;
return options.enabled
&& options.serial.size == sizeof(options.serial.bytes)
&& options.signature.size == sizeof(options.signature.bytes)
&& options.rsaN.size == sizeof(options.rsaN.bytes)
&& options.rsaE.size == sizeof(options.rsaE.bytes)
&& options.rsaD.size == sizeof(options.rsaD.bytes)
&& options.rsaP.size == sizeof(options.rsaP.bytes)
&& options.rsaQ.size == sizeof(options.rsaQ.bytes)
&& options.rsaDP.size == sizeof(options.rsaDP.bytes)
&& options.rsaDQ.size == sizeof(options.rsaDQ.bytes)
&& options.rsaQP.size == sizeof(options.rsaQP.bytes)
&& options.rsaRN.size == sizeof(options.rsaRN.bytes);
}
void PS4ModeAddon::setup() {
const PS4Options& options = Storage::getInstance().getAddonOptions().ps4Options;
memcpy(bytesN, options.rsaN.bytes, options.rsaN.size);
memcpy(bytesE, options.rsaE.bytes, options.rsaE.size);
memcpy(bytesD, options.rsaD.bytes, options.rsaD.size);
memcpy(bytesP, options.rsaP.bytes, options.rsaP.size);
memcpy(bytesQ, options.rsaQ.bytes, options.rsaQ.size);
memcpy(bytesDP, options.rsaDP.bytes, options.rsaDP.size);
memcpy(bytesDQ, options.rsaDQ.bytes, options.rsaDQ.size);
memcpy(bytesQP, options.rsaQP.bytes, options.rsaQP.size);
memcpy(bytesRN, options.rsaRN.bytes, options.rsaRN.size);
rsa_context = {
.ver = 0,
.len = 256,
.N = { .s=1, .n=64, .p=bytesN },
.E = { .s=1, .n=1, .p=bytesE },
.D = { .s=1, .n=64, .p=bytesD },
.P = { .s=1, .n=32, .p=bytesP },
.Q = { .s=1, .n=32, .p=bytesQ },
.DP = { .s=1, .n=32, .p=bytesDP },
.DQ = { .s=1, .n=32, .p=bytesDQ },
.QP = { .s=1, .n=32, .p=bytesQP },
.RN = { .s=1, .n=64, .p=bytesRN },
.RP = { .s=0, .n=0, .p=nullptr },
.RQ = { .s=0, .n=0, .p=nullptr },
.Vi = { .s=0, .n=0, .p=nullptr },
.Vf = { .s=0, .n=0, .p=nullptr },
.padding = MBEDTLS_RSA_PKCS_V21, .hash_id = MBEDTLS_MD_SHA256,
};
}
void PS4ModeAddon::process() {
const PS4Options& options = Storage::getInstance().getAddonOptions().ps4Options;
int rss_error = 0;
// Check to see if the PS4 Authentication needs work
if ( PS4Data::getInstance().ps4State == PS4State::nonce_ready ) {
// Generate some random for RNG
srand(getMillis());
auto rng = [](void*p_rng, unsigned char* p, size_t len) {
(void) p_rng;
p[0] = rand();
return 0;
};
uint8_t nonce_signature[256];
uint8_t * nonce_buffer = PS4Data::getInstance().nonce_buffer;
uint8_t * ps4_auth_buffer = PS4Data::getInstance().ps4_auth_buffer;
// Sign the nonce now that we got it!
//
if ( mbedtls_sha256_ret(nonce_buffer, 256, hashed_nonce, 0) < 0 ) {
return;
}
rss_error = mbedtls_rsa_rsassa_pss_sign(&rsa_context, rng, nullptr,
MBEDTLS_RSA_PRIVATE, MBEDTLS_MD_SHA256,
32, hashed_nonce,
nonce_signature);
if ( rss_error < 0 ) {
return;
}
// copy the parts into our authentication buffer
int offset = 0;
memcpy(&ps4_auth_buffer[offset], nonce_signature, 256);
offset += 256;
memcpy(&ps4_auth_buffer[offset], options.serial.bytes, 16);
offset += 16;
mbedtls_mpi* mpi = static_cast<mbedtls_mpi*>(&rsa_context.N);
mbedtls_mpi_write_binary(mpi, &ps4_auth_buffer[offset], 256);
offset += 256;
mpi = static_cast<mbedtls_mpi*>(&rsa_context.E);
mbedtls_mpi_write_binary(mpi, &ps4_auth_buffer[offset], 256);
offset += 256;
memcpy(&ps4_auth_buffer[offset], options.signature.bytes, 256);
offset += 256;
memset(&ps4_auth_buffer[offset], 0, 24);
PS4Data::getInstance().ps4State = PS4State::signed_nonce_ready; // signed and ready to party
}
}
/*
* SPDX-License-Identifier: MIT
* SPDX-FileCopyrightText: Copyright (c) 2021 Jason Skuby (mytechtoybox.com)
*/
#include "addons/ps4mode.h"
#include "helper.h"
#include "config.pb.h"
#include "ps4_driver.h"
#include "mbedtls/error.h"
#include "mbedtls/rsa.h"
#include "mbedtls/sha256.h"
bool PS4ModeAddon::available() {
const PS4Options& options = Storage::getInstance().getAddonOptions().ps4Options;
return options.enabled
&& options.serial.size == sizeof(options.serial.bytes)
&& options.signature.size == sizeof(options.signature.bytes)
&& options.rsaN.size == sizeof(options.rsaN.bytes)
&& options.rsaE.size == sizeof(options.rsaE.bytes)
&& options.rsaD.size == sizeof(options.rsaD.bytes)
&& options.rsaP.size == sizeof(options.rsaP.bytes)
&& options.rsaQ.size == sizeof(options.rsaQ.bytes)
&& options.rsaDP.size == sizeof(options.rsaDP.bytes)
&& options.rsaDQ.size == sizeof(options.rsaDQ.bytes)
&& options.rsaQP.size == sizeof(options.rsaQP.bytes)
&& options.rsaRN.size == sizeof(options.rsaRN.bytes);
}
void PS4ModeAddon::setup() {
const PS4Options& options = Storage::getInstance().getAddonOptions().ps4Options;
memcpy(bytesN, options.rsaN.bytes, options.rsaN.size);
memcpy(bytesE, options.rsaE.bytes, options.rsaE.size);
memcpy(bytesD, options.rsaD.bytes, options.rsaD.size);
memcpy(bytesP, options.rsaP.bytes, options.rsaP.size);
memcpy(bytesQ, options.rsaQ.bytes, options.rsaQ.size);
memcpy(bytesDP, options.rsaDP.bytes, options.rsaDP.size);
memcpy(bytesDQ, options.rsaDQ.bytes, options.rsaDQ.size);
memcpy(bytesQP, options.rsaQP.bytes, options.rsaQP.size);
memcpy(bytesRN, options.rsaRN.bytes, options.rsaRN.size);
rsa_context = {
.ver = 0,
.len = 256,
.N = { .s=1, .n=64, .p=bytesN },
.E = { .s=1, .n=1, .p=bytesE },
.D = { .s=1, .n=64, .p=bytesD },
.P = { .s=1, .n=32, .p=bytesP },
.Q = { .s=1, .n=32, .p=bytesQ },
.DP = { .s=1, .n=32, .p=bytesDP },
.DQ = { .s=1, .n=32, .p=bytesDQ },
.QP = { .s=1, .n=32, .p=bytesQP },
.RN = { .s=1, .n=64, .p=bytesRN },
.RP = { .s=0, .n=0, .p=nullptr },
.RQ = { .s=0, .n=0, .p=nullptr },
.Vi = { .s=0, .n=0, .p=nullptr },
.Vf = { .s=0, .n=0, .p=nullptr },
.padding = MBEDTLS_RSA_PKCS_V21, .hash_id = MBEDTLS_MD_SHA256,
};
}
void PS4ModeAddon::process() {
const PS4Options& options = Storage::getInstance().getAddonOptions().ps4Options;
int rss_error = 0;
// Check to see if the PS4 Authentication needs work
if ( PS4Data::getInstance().ps4State == PS4State::nonce_ready ) {
// Generate some random for RNG
srand(getMillis());
auto rng = [](void*p_rng, unsigned char* p, size_t len) {
(void) p_rng;
p[0] = rand();
return 0;
};
uint8_t nonce_signature[256];
uint8_t * nonce_buffer = PS4Data::getInstance().nonce_buffer;
uint8_t * ps4_auth_buffer = PS4Data::getInstance().ps4_auth_buffer;
// Sign the nonce now that we got it!
//
if ( mbedtls_sha256_ret(nonce_buffer, 256, hashed_nonce, 0) < 0 ) {
return;
}
rss_error = mbedtls_rsa_rsassa_pss_sign(&rsa_context, rng, nullptr,
MBEDTLS_RSA_PRIVATE, MBEDTLS_MD_SHA256,
32, hashed_nonce,
nonce_signature);
if ( rss_error < 0 ) {
return;
}
// copy the parts into our authentication buffer
int offset = 0;
memcpy(&ps4_auth_buffer[offset], nonce_signature, 256);
offset += 256;
memcpy(&ps4_auth_buffer[offset], options.serial.bytes, 16);
offset += 16;
mbedtls_mpi* mpi = static_cast<mbedtls_mpi*>(&rsa_context.N);
mbedtls_mpi_write_binary(mpi, &ps4_auth_buffer[offset], 256);
offset += 256;
mpi = static_cast<mbedtls_mpi*>(&rsa_context.E);
mbedtls_mpi_write_binary(mpi, &ps4_auth_buffer[offset], 256);
offset += 256;
memcpy(&ps4_auth_buffer[offset], options.signature.bytes, 256);
offset += 256;
memset(&ps4_auth_buffer[offset], 0, 24);
PS4Data::getInstance().ps4State = PS4State::signed_nonce_ready; // signed and ready to party
}
}

View File

@@ -1,3 +1,3 @@
VITE_CURRENT_VERSION=v0.7.2
VITE_GP2040_BOARD=pico
VITE_GP2040_CONTROLLER=pico
VITE_CURRENT_VERSION=v0.7.2
VITE_GP2040_BOARD=pico
VITE_GP2040_CONTROLLER=pico

View File

@@ -1,24 +1,24 @@
env:
node: true
browser: true
es2021: true
extends:
- eslint:recommended
- plugin:react/recommended
- plugin:react-hooks/recommended
overrides: []
parserOptions:
ecmaVersion: latest
sourceType: module
settings:
react:
version: "18.2"
plugins:
- react-refresh
rules:
react-refresh/only-export-components: warn
react/prop-types: off
no-template-curly-in-string: off
no-unused-vars: off
react-hooks/exhaustive-deps: off
no-extra-boolean-cast: off
env:
node: true
browser: true
es2021: true
extends:
- eslint:recommended
- plugin:react/recommended
- plugin:react-hooks/recommended
overrides: []
parserOptions:
ecmaVersion: latest
sourceType: module
settings:
react:
version: "18.2"
plugins:
- react-refresh
rules:
react-refresh/only-export-components: warn
react/prop-types: off
no-template-curly-in-string: off
no-unused-vars: off
react-hooks/exhaustive-deps: off
no-extra-boolean-cast: off

View File

@@ -1,27 +1,27 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web configuration application for GP2040-CE gamepad firmware"
/>
<link rel="icon" href="/favicon.ico" />
<link rel="apple-touch-icon" href="/logo.png" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="/manifest.json" />
<title>GP2040-CE Configurator</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<script type="module" src="/src/index.jsx"></script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web configuration application for GP2040-CE gamepad firmware"
/>
<link rel="icon" href="/favicon.ico" />
<link rel="apple-touch-icon" href="/logo.png" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="/manifest.json" />
<title>GP2040-CE Configurator</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<script type="module" src="/src/index.jsx"></script>
</body>
</html>

View File

@@ -1,305 +1,305 @@
/**
* GP2040-CE Configurator Development Server
*/
import express from "express";
import cors from "cors";
import mapValues from "lodash/mapValues.js";
import { readFileSync } from "fs";
import path from "path";
import { fileURLToPath } from "url";
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const { pico: picoController } = JSON.parse(
readFileSync(path.resolve(__dirname, "../src/Data/Controllers.json"), "utf8")
);
const { keyboard: keyboardMapping } = JSON.parse(
readFileSync(path.resolve(__dirname, "../src/Data/Keyboard.json"), "utf8")
);
const port = process.env.PORT || 8080;
const app = express();
app.use(cors());
app.use(express.json());
app.use((req, res, next) => {
console.log("Request:", req.method, req.url);
next();
});
app.get("/api/getUsedPins", (req, res) => {
return res.send({ usedPins: Object.values(picoController) });
});
app.get("/api/resetSettings", (req, res) => {
return res.send({ success: true });
});
app.get("/api/getDisplayOptions", (req, res) => {
const data = {
enabled: 1,
sdaPin: 0,
sclPin: 1,
i2cAddress: "0x3D",
i2cBlock: 0,
i2cSpeed: 400000,
flipDisplay: 0,
invertDisplay: 1,
buttonLayout: 0,
buttonLayoutRight: 3,
splashMode: 3,
splashChoice: 0,
splashDuration: 0,
splashImage: Array(16 * 64).fill(255),
buttonLayoutCustomOptions: {
params: {
layout: 2,
startX: 8,
startY: 28,
buttonRadius: 8,
buttonPadding: 2,
},
paramsRight: {
layout: 9,
startX: 8,
startY: 28,
buttonRadius: 8,
buttonPadding: 2,
},
},
displaySaverTimeout: 0,
};
console.log("data", data);
return res.send(data);
});
app.get("/api/getSplashImage", (req, res) => {
const data = {
splashImage: Array(16 * 64).fill(255),
};
console.log("data", data);
return res.send(data);
});
app.get("/api/getGamepadOptions", (req, res) => {
return res.send({
dpadMode: 0,
inputMode: 4,
socdMode: 2,
switchTpShareForDs4: 0,
forcedSetupMode: 0,
lockHotkeys: 0,
hotkeyF1: [
{ action: 1, mask: 1 << 0 },
{ action: 2, mask: 1 << 1 },
{ action: 3, mask: 1 << 2 },
{ action: 4, mask: 1 << 3 },
],
hotkeyF2: [
{ action: 5, mask: 1 << 0 },
{ action: 6, mask: 1 << 1 },
{ action: 7, mask: 1 << 2 },
{ action: 8, mask: 1 << 3 },
],
});
});
app.get("/api/getLedOptions", (req, res) => {
return res.send({
brightnessMaximum: 255,
brightnessSteps: 5,
dataPin: 15,
ledFormat: 0,
ledLayout: 1,
ledsPerButton: 2,
ledButtonMap: {
Up: 3,
Down: 1,
Left: 0,
Right: 2,
B1: 8,
B2: 9,
B3: 4,
B4: 5,
L1: 7,
R1: 6,
L2: 11,
R2: 10,
S1: null,
S2: null,
L3: null,
R3: null,
A1: null,
A2: null,
},
usedPins: Object.values(picoController),
pledType: 1,
pledPin1: 12,
pledPin2: 13,
pledPin3: 14,
pledPin4: 15,
pledColor: 65280,
});
});
app.get("/api/getCustomTheme", (req, res) => {
console.log("/api/getCustomTheme");
return res.send({
enabled: true,
Up: { u: 16711680, d: 255 },
Down: { u: 16711680, d: 255 },
Left: { u: 16711680, d: 255 },
Right: { u: 16711680, d: 255 },
B1: { u: 65280, d: 16711680 },
B2: { u: 65280, d: 16711680 },
B3: { u: 255, d: 65280 },
B4: { u: 255, d: 65280 },
L1: { u: 255, d: 65280 },
R1: { u: 255, d: 65280 },
L2: { u: 65280, d: 16711680 },
R2: { u: 65280, d: 16711680 },
S1: { u: 65535, d: 16776960 },
S2: { u: 65535, d: 16776960 },
L3: { u: 65416, d: 16746496 },
R3: { u: 65416, d: 16746496 },
A1: { u: 8913151, d: 65416 },
A2: { u: 8913151, d: 65416 },
});
});
app.get("/api/getPinMappings", (req, res) => {
return res.send(picoController);
});
app.get("/api/getKeyMappings", (req, res) =>
res.send(mapValues(keyboardMapping))
);
app.get("/api/getAddonsOptions", (req, res) => {
return res.send({
turboPin: -1,
turboPinLED: -1,
sliderLSPin: -1,
sliderRSPin: -1,
sliderSOCDPinOne: -1,
sliderSOCDPinTwo: -1,
turboShotCount: 20,
reversePin: -1,
reversePinLED: -1,
reverseActionUp: 1,
reverseActionDown: 1,
reverseActionLeft: 1,
reverseActionRight: 1,
i2cAnalog1219SDAPin: -1,
i2cAnalog1219SCLPin: -1,
i2cAnalog1219Block: 0,
i2cAnalog1219Speed: 400000,
i2cAnalog1219Address: 0x40,
onBoardLedMode: 0,
dualDirUpPin: -1,
dualDirDownPin: -1,
dualDirLeftPin: -1,
dualDirRightPin: -1,
dualDirDpadMode: 0,
dualDirCombineMode: 0,
analogAdcPinX: -1,
analogAdcPinY: -1,
bootselButtonMap: 0,
buzzerPin: -1,
buzzerVolume: 100,
extraButtonPin: -1,
extraButtonMap: 0,
playerNumber: 1,
shmupMode: 0,
shmupMixMode: 0,
shmupAlwaysOn1: 0,
shmupAlwaysOn2: 0,
shmupAlwaysOn3: 0,
shmupAlwaysOn4: 0,
pinShmupBtn1: -1,
pinShmupBtn2: -1,
pinShmupBtn3: -1,
pinShmupBtn4: -1,
shmupBtnMask1: 0,
shmupBtnMask2: 0,
shmupBtnMask3: 0,
shmupBtnMask4: 0,
pinShmupDial: -1,
sliderSOCDModeOne: 0,
sliderSOCDModeTwo: 2,
sliderSOCDModeDefault: 1,
wiiExtensionSDAPin: -1,
wiiExtensionSCLPin: -1,
wiiExtensionBlock: 0,
wiiExtensionSpeed: 400000,
snesPadClockPin: -1,
snesPadLatchPin: -1,
snesPadDataPin: -1,
AnalogInputEnabled: 1,
BoardLedAddonEnabled: 1,
BuzzerSpeakerAddonEnabled: 1,
BootselButtonAddonEnabled: 1,
DualDirectionalInputEnabled: 1,
ExtraButtonAddonEnabled: 1,
I2CAnalog1219InputEnabled: 1,
JSliderInputEnabled: 1,
PlayerNumAddonEnabled: 1,
PS4ModeAddonEnabled: 1,
ReverseInputEnabled: 1,
SliderSOCDInputEnabled: 1,
TurboInputEnabled: 1,
WiiExtensionAddonEnabled: 1,
SNESpadAddonEnabled: 1,
usedPins: Object.values(picoController),
});
});
app.get("/api/getFirmwareVersion", (req, res) => {
return res.send({
version: process.env.VITE_CURRENT_VERSION,
});
});
app.get("/api/getButtonLayoutCustomOptions", (req, res) => {
return res.send({
params: {
layout: 2,
startX: 8,
startY: 28,
buttonRadius: 8,
buttonPadding: 2,
},
paramsRight: {
layout: 9,
startX: 8,
startY: 28,
buttonRadius: 8,
buttonPadding: 2,
},
});
});
app.get("/api/reboot", (req, res) => {
return res.send({});
});
app.get("/api/getMemoryReport", (req, res) => {
return res.send({
totalFlash: 2048,
usedFlash: 1048,
staticAllocs: 200,
totalHeap: 2048,
usedHeap: 1048,
});
});
app.post("/api/*", (req, res) => {
console.log(req.body);
return res.send(req.body);
});
app.listen(port, () => {
console.log(`Dev app listening at http://localhost:${port}`);
});
/**
* GP2040-CE Configurator Development Server
*/
import express from "express";
import cors from "cors";
import mapValues from "lodash/mapValues.js";
import { readFileSync } from "fs";
import path from "path";
import { fileURLToPath } from "url";
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const { pico: picoController } = JSON.parse(
readFileSync(path.resolve(__dirname, "../src/Data/Controllers.json"), "utf8")
);
const { keyboard: keyboardMapping } = JSON.parse(
readFileSync(path.resolve(__dirname, "../src/Data/Keyboard.json"), "utf8")
);
const port = process.env.PORT || 8080;
const app = express();
app.use(cors());
app.use(express.json());
app.use((req, res, next) => {
console.log("Request:", req.method, req.url);
next();
});
app.get("/api/getUsedPins", (req, res) => {
return res.send({ usedPins: Object.values(picoController) });
});
app.get("/api/resetSettings", (req, res) => {
return res.send({ success: true });
});
app.get("/api/getDisplayOptions", (req, res) => {
const data = {
enabled: 1,
sdaPin: 0,
sclPin: 1,
i2cAddress: "0x3D",
i2cBlock: 0,
i2cSpeed: 400000,
flipDisplay: 0,
invertDisplay: 1,
buttonLayout: 0,
buttonLayoutRight: 3,
splashMode: 3,
splashChoice: 0,
splashDuration: 0,
splashImage: Array(16 * 64).fill(255),
buttonLayoutCustomOptions: {
params: {
layout: 2,
startX: 8,
startY: 28,
buttonRadius: 8,
buttonPadding: 2,
},
paramsRight: {
layout: 9,
startX: 8,
startY: 28,
buttonRadius: 8,
buttonPadding: 2,
},
},
displaySaverTimeout: 0,
};
console.log("data", data);
return res.send(data);
});
app.get("/api/getSplashImage", (req, res) => {
const data = {
splashImage: Array(16 * 64).fill(255),
};
console.log("data", data);
return res.send(data);
});
app.get("/api/getGamepadOptions", (req, res) => {
return res.send({
dpadMode: 0,
inputMode: 4,
socdMode: 2,
switchTpShareForDs4: 0,
forcedSetupMode: 0,
lockHotkeys: 0,
hotkeyF1: [
{ action: 1, mask: 1 << 0 },
{ action: 2, mask: 1 << 1 },
{ action: 3, mask: 1 << 2 },
{ action: 4, mask: 1 << 3 },
],
hotkeyF2: [
{ action: 5, mask: 1 << 0 },
{ action: 6, mask: 1 << 1 },
{ action: 7, mask: 1 << 2 },
{ action: 8, mask: 1 << 3 },
],
});
});
app.get("/api/getLedOptions", (req, res) => {
return res.send({
brightnessMaximum: 255,
brightnessSteps: 5,
dataPin: 15,
ledFormat: 0,
ledLayout: 1,
ledsPerButton: 2,
ledButtonMap: {
Up: 3,
Down: 1,
Left: 0,
Right: 2,
B1: 8,
B2: 9,
B3: 4,
B4: 5,
L1: 7,
R1: 6,
L2: 11,
R2: 10,
S1: null,
S2: null,
L3: null,
R3: null,
A1: null,
A2: null,
},
usedPins: Object.values(picoController),
pledType: 1,
pledPin1: 12,
pledPin2: 13,
pledPin3: 14,
pledPin4: 15,
pledColor: 65280,
});
});
app.get("/api/getCustomTheme", (req, res) => {
console.log("/api/getCustomTheme");
return res.send({
enabled: true,
Up: { u: 16711680, d: 255 },
Down: { u: 16711680, d: 255 },
Left: { u: 16711680, d: 255 },
Right: { u: 16711680, d: 255 },
B1: { u: 65280, d: 16711680 },
B2: { u: 65280, d: 16711680 },
B3: { u: 255, d: 65280 },
B4: { u: 255, d: 65280 },
L1: { u: 255, d: 65280 },
R1: { u: 255, d: 65280 },
L2: { u: 65280, d: 16711680 },
R2: { u: 65280, d: 16711680 },
S1: { u: 65535, d: 16776960 },
S2: { u: 65535, d: 16776960 },
L3: { u: 65416, d: 16746496 },
R3: { u: 65416, d: 16746496 },
A1: { u: 8913151, d: 65416 },
A2: { u: 8913151, d: 65416 },
});
});
app.get("/api/getPinMappings", (req, res) => {
return res.send(picoController);
});
app.get("/api/getKeyMappings", (req, res) =>
res.send(mapValues(keyboardMapping))
);
app.get("/api/getAddonsOptions", (req, res) => {
return res.send({
turboPin: -1,
turboPinLED: -1,
sliderLSPin: -1,
sliderRSPin: -1,
sliderSOCDPinOne: -1,
sliderSOCDPinTwo: -1,
turboShotCount: 20,
reversePin: -1,
reversePinLED: -1,
reverseActionUp: 1,
reverseActionDown: 1,
reverseActionLeft: 1,
reverseActionRight: 1,
i2cAnalog1219SDAPin: -1,
i2cAnalog1219SCLPin: -1,
i2cAnalog1219Block: 0,
i2cAnalog1219Speed: 400000,
i2cAnalog1219Address: 0x40,
onBoardLedMode: 0,
dualDirUpPin: -1,
dualDirDownPin: -1,
dualDirLeftPin: -1,
dualDirRightPin: -1,
dualDirDpadMode: 0,
dualDirCombineMode: 0,
analogAdcPinX: -1,
analogAdcPinY: -1,
bootselButtonMap: 0,
buzzerPin: -1,
buzzerVolume: 100,
extraButtonPin: -1,
extraButtonMap: 0,
playerNumber: 1,
shmupMode: 0,
shmupMixMode: 0,
shmupAlwaysOn1: 0,
shmupAlwaysOn2: 0,
shmupAlwaysOn3: 0,
shmupAlwaysOn4: 0,
pinShmupBtn1: -1,
pinShmupBtn2: -1,
pinShmupBtn3: -1,
pinShmupBtn4: -1,
shmupBtnMask1: 0,
shmupBtnMask2: 0,
shmupBtnMask3: 0,
shmupBtnMask4: 0,
pinShmupDial: -1,
sliderSOCDModeOne: 0,
sliderSOCDModeTwo: 2,
sliderSOCDModeDefault: 1,
wiiExtensionSDAPin: -1,
wiiExtensionSCLPin: -1,
wiiExtensionBlock: 0,
wiiExtensionSpeed: 400000,
snesPadClockPin: -1,
snesPadLatchPin: -1,
snesPadDataPin: -1,
AnalogInputEnabled: 1,
BoardLedAddonEnabled: 1,
BuzzerSpeakerAddonEnabled: 1,
BootselButtonAddonEnabled: 1,
DualDirectionalInputEnabled: 1,
ExtraButtonAddonEnabled: 1,
I2CAnalog1219InputEnabled: 1,
JSliderInputEnabled: 1,
PlayerNumAddonEnabled: 1,
PS4ModeAddonEnabled: 1,
ReverseInputEnabled: 1,
SliderSOCDInputEnabled: 1,
TurboInputEnabled: 1,
WiiExtensionAddonEnabled: 1,
SNESpadAddonEnabled: 1,
usedPins: Object.values(picoController),
});
});
app.get("/api/getFirmwareVersion", (req, res) => {
return res.send({
version: process.env.VITE_CURRENT_VERSION,
});
});
app.get("/api/getButtonLayoutCustomOptions", (req, res) => {
return res.send({
params: {
layout: 2,
startX: 8,
startY: 28,
buttonRadius: 8,
buttonPadding: 2,
},
paramsRight: {
layout: 9,
startX: 8,
startY: 28,
buttonRadius: 8,
buttonPadding: 2,
},
});
});
app.get("/api/reboot", (req, res) => {
return res.send({});
});
app.get("/api/getMemoryReport", (req, res) => {
return res.send({
totalFlash: 2048,
usedFlash: 1048,
staticAllocs: 200,
totalHeap: 2048,
usedHeap: 1048,
});
});
app.post("/api/*", (req, res) => {
console.log(req.body);
return res.send(req.body);
});
app.listen(port, () => {
console.log(`Dev app listening at http://localhost:${port}`);
});

View File

@@ -1,62 +1,62 @@
import React, { useContext } from "react";
import { Dropdown } from "react-bootstrap";
import { AppContext } from "../Contexts/AppContext";
import SunIcon from "../Icons/Sun";
import MoonStarsIcon from "../Icons/MoonStars";
import CircleHalfIcon from "../Icons/CircleHalf";
const dropdownOptions = [
{ scheme: "light", icon: SunIcon, label: "Light" },
{ scheme: "dark", icon: MoonStarsIcon, label: "Dark" },
{ scheme: "auto", icon: CircleHalfIcon, label: "Auto" },
];
const setTheme = function (theme) {
const rootElement = document.documentElement;
const prefersDarkMode = window.matchMedia(
"(prefers-color-scheme: dark)"
).matches;
if (theme === "auto") {
rootElement.setAttribute(
"data-bs-theme",
prefersDarkMode ? "dark" : "light"
);
} else {
rootElement.setAttribute("data-bs-theme", theme);
}
};
const ColorScheme = () => {
const { savedColorScheme, setSavedColorScheme } = useContext(AppContext);
setTheme(savedColorScheme);
const setThemeAndState = (newColorScheme) => {
setTheme(newColorScheme);
setSavedColorScheme(newColorScheme);
};
return (
<Dropdown>
<Dropdown.Toggle variant="secondary" style={{ marginRight: "7px" }}>
<MoonStarsIcon />
</Dropdown.Toggle>
<Dropdown.Menu>
{dropdownOptions.map((option) => (
<Dropdown.Item
key={option.theme}
as={"button"}
className={savedColorScheme === option.scheme ? "active" : ""}
onClick={() => setThemeAndState(option.scheme)}
>
<option.icon /> {option.label}
</Dropdown.Item>
))}
</Dropdown.Menu>
</Dropdown>
);
};
export default ColorScheme;
import React, { useContext } from "react";
import { Dropdown } from "react-bootstrap";
import { AppContext } from "../Contexts/AppContext";
import SunIcon from "../Icons/Sun";
import MoonStarsIcon from "../Icons/MoonStars";
import CircleHalfIcon from "../Icons/CircleHalf";
const dropdownOptions = [
{ scheme: "light", icon: SunIcon, label: "Light" },
{ scheme: "dark", icon: MoonStarsIcon, label: "Dark" },
{ scheme: "auto", icon: CircleHalfIcon, label: "Auto" },
];
const setTheme = function (theme) {
const rootElement = document.documentElement;
const prefersDarkMode = window.matchMedia(
"(prefers-color-scheme: dark)"
).matches;
if (theme === "auto") {
rootElement.setAttribute(
"data-bs-theme",
prefersDarkMode ? "dark" : "light"
);
} else {
rootElement.setAttribute("data-bs-theme", theme);
}
};
const ColorScheme = () => {
const { savedColorScheme, setSavedColorScheme } = useContext(AppContext);
setTheme(savedColorScheme);
const setThemeAndState = (newColorScheme) => {
setTheme(newColorScheme);
setSavedColorScheme(newColorScheme);
};
return (
<Dropdown>
<Dropdown.Toggle variant="secondary" style={{ marginRight: "7px" }}>
<MoonStarsIcon />
</Dropdown.Toggle>
<Dropdown.Menu>
{dropdownOptions.map((option) => (
<Dropdown.Item
key={option.theme}
as={"button"}
className={savedColorScheme === option.scheme ? "active" : ""}
onClick={() => setThemeAndState(option.scheme)}
>
<option.icon /> {option.label}
</Dropdown.Item>
))}
</Dropdown.Menu>
</Dropdown>
);
};
export default ColorScheme;

View File

@@ -1,13 +1,13 @@
import React from "react";
const CircleHalf = () => (
<svg
xmlns="http://www.w3.org/2000/svg"
width="1em"
height="1em"
fill="currentColor"
>
<path d="M8 15A7 7 0 1 0 8 1v14zm0 1A8 8 0 1 1 8 0a8 8 0 0 1 0 16z" />
</svg>
);
export default CircleHalf;
import React from "react";
const CircleHalf = () => (
<svg
xmlns="http://www.w3.org/2000/svg"
width="1em"
height="1em"
fill="currentColor"
>
<path d="M8 15A7 7 0 1 0 8 1v14zm0 1A8 8 0 1 1 8 0a8 8 0 0 1 0 16z" />
</svg>
);
export default CircleHalf;

View File

@@ -1,14 +1,14 @@
import React from "react";
const MoonStars = () => (
<svg
xmlns="http://www.w3.org/2000/svg"
width="1em"
height="1em"
fill="currentColor"
>
<path d="M6 .278a.768.768 0 0 1 .08.858 7.208 7.208 0 0 0-.878 3.46c0 4.021 3.278 7.277 7.318 7.277.527 0 1.04-.055 1.533-.16a.787.787 0 0 1 .81.316.733.733 0 0 1-.031.893A8.349 8.349 0 0 1 8.344 16C3.734 16 0 12.286 0 7.71 0 4.266 2.114 1.312 5.124.06A.752.752 0 0 1 6 .278z" />
<path d="M10.794 3.148a.217.217 0 0 1 .412 0l.387 1.162c.173.518.579.924 1.097 1.097l1.162.387a.217.217 0 0 1 0 .412l-1.162.387a1.734 1.734 0 0 0-1.097 1.097l-.387 1.162a.217.217 0 0 1-.412 0l-.387-1.162A1.734 1.734 0 0 0 9.31 6.593l-1.162-.387a.217.217 0 0 1 0-.412l1.162-.387a1.734 1.734 0 0 0 1.097-1.097l.387-1.162zM13.863.099a.145.145 0 0 1 .274 0l.258.774c.115.346.386.617.732.732l.774.258a.145.145 0 0 1 0 .274l-.774.258a1.156 1.156 0 0 0-.732.732l-.258.774a.145.145 0 0 1-.274 0l-.258-.774a1.156 1.156 0 0 0-.732-.732l-.774-.258a.145.145 0 0 1 0-.274l.774-.258c.346-.115.617-.386.732-.732L13.863.1z" />
</svg>
);
export default MoonStars;
import React from "react";
const MoonStars = () => (
<svg
xmlns="http://www.w3.org/2000/svg"
width="1em"
height="1em"
fill="currentColor"
>
<path d="M6 .278a.768.768 0 0 1 .08.858 7.208 7.208 0 0 0-.878 3.46c0 4.021 3.278 7.277 7.318 7.277.527 0 1.04-.055 1.533-.16a.787.787 0 0 1 .81.316.733.733 0 0 1-.031.893A8.349 8.349 0 0 1 8.344 16C3.734 16 0 12.286 0 7.71 0 4.266 2.114 1.312 5.124.06A.752.752 0 0 1 6 .278z" />
<path d="M10.794 3.148a.217.217 0 0 1 .412 0l.387 1.162c.173.518.579.924 1.097 1.097l1.162.387a.217.217 0 0 1 0 .412l-1.162.387a1.734 1.734 0 0 0-1.097 1.097l-.387 1.162a.217.217 0 0 1-.412 0l-.387-1.162A1.734 1.734 0 0 0 9.31 6.593l-1.162-.387a.217.217 0 0 1 0-.412l1.162-.387a1.734 1.734 0 0 0 1.097-1.097l.387-1.162zM13.863.099a.145.145 0 0 1 .274 0l.258.774c.115.346.386.617.732.732l.774.258a.145.145 0 0 1 0 .274l-.774.258a1.156 1.156 0 0 0-.732.732l-.258.774a.145.145 0 0 1-.274 0l-.258-.774a1.156 1.156 0 0 0-.732-.732l-.774-.258a.145.145 0 0 1 0-.274l.774-.258c.346-.115.617-.386.732-.732L13.863.1z" />
</svg>
);
export default MoonStars;

View File

@@ -1,13 +1,13 @@
import React from "react";
const Sun = () => (
<svg
xmlns="http://www.w3.org/2000/svg"
width="1em"
height="1em"
fill="currentColor"
>
<path d="M8 12a4 4 0 1 0 0-8 4 4 0 0 0 0 8zM8 0a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-1 0v-2A.5.5 0 0 1 8 0zm0 13a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-1 0v-2A.5.5 0 0 1 8 13zm8-5a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1 0-1h2a.5.5 0 0 1 .5.5zM3 8a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1 0-1h2A.5.5 0 0 1 3 8zm10.657-5.657a.5.5 0 0 1 0 .707l-1.414 1.415a.5.5 0 1 1-.707-.708l1.414-1.414a.5.5 0 0 1 .707 0zm-9.193 9.193a.5.5 0 0 1 0 .707L3.05 13.657a.5.5 0 0 1-.707-.707l1.414-1.414a.5.5 0 0 1 .707 0zm9.193 2.121a.5.5 0 0 1-.707 0l-1.414-1.414a.5.5 0 0 1 .707-.707l1.414 1.414a.5.5 0 0 1 0 .707zM4.464 4.465a.5.5 0 0 1-.707 0L2.343 3.05a.5.5 0 1 1 .707-.707l1.414 1.414a.5.5 0 0 1 0 .708z" />
</svg>
);
export default Sun;
import React from "react";
const Sun = () => (
<svg
xmlns="http://www.w3.org/2000/svg"
width="1em"
height="1em"
fill="currentColor"
>
<path d="M8 12a4 4 0 1 0 0-8 4 4 0 0 0 0 8zM8 0a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-1 0v-2A.5.5 0 0 1 8 0zm0 13a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-1 0v-2A.5.5 0 0 1 8 13zm8-5a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1 0-1h2a.5.5 0 0 1 .5.5zM3 8a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1 0-1h2A.5.5 0 0 1 3 8zm10.657-5.657a.5.5 0 0 1 0 .707l-1.414 1.415a.5.5 0 1 1-.707-.708l1.414-1.414a.5.5 0 0 1 .707 0zm-9.193 9.193a.5.5 0 0 1 0 .707L3.05 13.657a.5.5 0 0 1-.707-.707l1.414-1.414a.5.5 0 0 1 .707 0zm9.193 2.121a.5.5 0 0 1-.707 0l-1.414-1.414a.5.5 0 0 1 .707-.707l1.414 1.414a.5.5 0 0 1 0 .707zM4.464 4.465a.5.5 0 0 1-.707 0L2.343 3.05a.5.5 0 1 1 .707-.707l1.414 1.414a.5.5 0 0 1 0 .708z" />
</svg>
);
export default Sun;

View File

@@ -1,8 +1,8 @@
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import "./index.scss";
import "bootstrap/dist/js/bootstrap.bundle.min.js";
ReactDOM.createRoot(document.getElementById("root")).render(<App />);
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import "./index.scss";
import "bootstrap/dist/js/bootstrap.bundle.min.js";
ReactDOM.createRoot(document.getElementById("root")).render(<App />);

View File

@@ -1,21 +1,21 @@
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import path from "path";
// https://vitejs.dev/config/
export default defineConfig({
build: {
outDir: path.join(__dirname, "build"),
sourcemap: false,
},
server: {
open: true,
port: 3000,
},
plugins: [react()],
resolve: {
alias: {
"~bootstrap": path.resolve(__dirname, "node_modules/bootstrap"),
},
},
});
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import path from "path";
// https://vitejs.dev/config/
export default defineConfig({
build: {
outDir: path.join(__dirname, "build"),
sourcemap: false,
},
server: {
open: true,
port: 3000,
},
plugins: [react()],
resolve: {
alias: {
"~bootstrap": path.resolve(__dirname, "node_modules/bootstrap"),
},
},
});