parent
708bb4f55d
commit
09ff4b0c99
@ -0,0 +1,62 @@ |
|||||||
|
/* Copyright 2019 Jack Humbert
|
||||||
|
* |
||||||
|
* This program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU General Public License as published by |
||||||
|
* the Free Software Foundation, either version 2 of the License, or |
||||||
|
* (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/ |
||||||
|
|
||||||
|
#pragma once |
||||||
|
|
||||||
|
#include "config_common.h" |
||||||
|
|
||||||
|
/* USB Device descriptor parameter */ |
||||||
|
#define VENDOR_ID 0x0e6f |
||||||
|
#define PRODUCT_ID 0x0185 |
||||||
|
#define DEVICE_VER 0x0001 |
||||||
|
#define MANUFACTURER QMK |
||||||
|
#define PRODUCT Proton C |
||||||
|
#define DESCRIPTION Handwired Gamepad |
||||||
|
|
||||||
|
/* key matrix size */ |
||||||
|
#define MATRIX_ROWS 1 |
||||||
|
#define MATRIX_COLS 1 |
||||||
|
|
||||||
|
#define DIODE_DIRECTION COL2ROW |
||||||
|
|
||||||
|
#define MATRIX_COL_PINS { A3 } |
||||||
|
#define MATRIX_ROW_PINS { A1 } |
||||||
|
|
||||||
|
/* define if matrix has ghost */ |
||||||
|
//#define MATRIX_HAS_GHOST
|
||||||
|
|
||||||
|
/* Set 0 if debouncing isn't needed */ |
||||||
|
#define DEBOUNCE 5 |
||||||
|
|
||||||
|
/*
|
||||||
|
* Feature disable options |
||||||
|
* These options are also useful to firmware size reduction. |
||||||
|
*/ |
||||||
|
|
||||||
|
/* disable debug print */ |
||||||
|
//#define NO_DEBUG
|
||||||
|
|
||||||
|
/* disable print */ |
||||||
|
//#define NO_PRINT
|
||||||
|
|
||||||
|
/* disable action features */ |
||||||
|
//#define NO_ACTION_LAYER
|
||||||
|
//#define NO_ACTION_TAPPING
|
||||||
|
//#define NO_ACTION_ONESHOT
|
||||||
|
//#define NO_ACTION_MACRO
|
||||||
|
//#define NO_ACTION_FUNCTION
|
||||||
|
|
||||||
|
#define GAMECUBE_DATA_PIN A2 |
@ -0,0 +1,130 @@ |
|||||||
|
#include "gc_controller.h" |
||||||
|
#include "gc_read.h" |
||||||
|
#include "gamepad.h" |
||||||
|
#include <string.h> |
||||||
|
|
||||||
|
uint16_t gamecube_buttons = 0; |
||||||
|
uint8_t gamecube_joysticks[6] = {0}; |
||||||
|
bool z_button = false; |
||||||
|
|
||||||
|
report_gamepad_t report = { |
||||||
|
.Button = 0, |
||||||
|
.LX = STICK_CENTER, |
||||||
|
.LY = STICK_CENTER, |
||||||
|
.RX = STICK_CENTER, |
||||||
|
.RY = STICK_CENTER, |
||||||
|
.HAT = HAT_CENTER |
||||||
|
}; |
||||||
|
|
||||||
|
void board_init(void) { |
||||||
|
setPinOutput(C13); |
||||||
|
writePinLow(C13); |
||||||
|
gamecube_init(); |
||||||
|
} |
||||||
|
|
||||||
|
void matrix_init_user(void) { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
void matrix_scan_user(void) { |
||||||
|
|
||||||
|
gamecube_scan(&gamecube_buttons, gamecube_joysticks); |
||||||
|
|
||||||
|
z_button = gamecube_buttons & GAMECUBE_Z; |
||||||
|
|
||||||
|
// Home & Capture
|
||||||
|
if (gamecube_buttons & GAMECUBE_START) { |
||||||
|
if (z_button && !(report.Button & SWITCH_HOME)) |
||||||
|
report.Button |= SWITCH_CAPTURE; |
||||||
|
else |
||||||
|
report.Button |= SWITCH_HOME; |
||||||
|
} else { |
||||||
|
report.Button &= ~SWITCH_HOME; |
||||||
|
report.Button &= ~SWITCH_CAPTURE; |
||||||
|
} |
||||||
|
// Y and L
|
||||||
|
if (gamecube_buttons & GAMECUBE_Y) { |
||||||
|
if (z_button && !(report.Button & SWITCH_Y)) |
||||||
|
report.Button |= SWITCH_L; |
||||||
|
else |
||||||
|
report.Button |= SWITCH_Y; |
||||||
|
} else { |
||||||
|
report.Button &= ~SWITCH_Y; |
||||||
|
report.Button &= ~SWITCH_L; |
||||||
|
} |
||||||
|
// X and R
|
||||||
|
if (gamecube_buttons & GAMECUBE_X) { |
||||||
|
if (z_button && !(report.Button & SWITCH_X)) |
||||||
|
report.Button |= SWITCH_R; |
||||||
|
else |
||||||
|
report.Button |= SWITCH_X; |
||||||
|
} else { |
||||||
|
report.Button &= ~SWITCH_X; |
||||||
|
report.Button &= ~SWITCH_R; |
||||||
|
} |
||||||
|
// B and -
|
||||||
|
if (gamecube_buttons & GAMECUBE_B) { |
||||||
|
if (z_button && !(report.Button & SWITCH_B)) |
||||||
|
report.Button |= SWITCH_MINUS; |
||||||
|
else |
||||||
|
report.Button |= SWITCH_B; |
||||||
|
} else { |
||||||
|
report.Button &= ~SWITCH_B; |
||||||
|
report.Button &= ~SWITCH_MINUS; |
||||||
|
} |
||||||
|
// A and +
|
||||||
|
if (gamecube_buttons & GAMECUBE_A) { |
||||||
|
if (z_button && !(report.Button & SWITCH_A)) |
||||||
|
report.Button |= SWITCH_PLUS; |
||||||
|
else |
||||||
|
report.Button |= SWITCH_A; |
||||||
|
} else { |
||||||
|
report.Button &= ~SWITCH_A; |
||||||
|
report.Button &= ~SWITCH_PLUS; |
||||||
|
} |
||||||
|
|
||||||
|
if (gamecube_buttons & GAMECUBE_L) { |
||||||
|
report.Button |= SWITCH_ZL; |
||||||
|
} else { |
||||||
|
report.Button &= ~SWITCH_ZL; |
||||||
|
} |
||||||
|
if (gamecube_buttons & GAMECUBE_R) { |
||||||
|
report.Button |= SWITCH_ZR; |
||||||
|
} else { |
||||||
|
report.Button &= ~SWITCH_ZR; |
||||||
|
} |
||||||
|
|
||||||
|
if ((gamecube_buttons & GAMECUBE_UP) && (gamecube_buttons & GAMECUBE_RIGHT)) |
||||||
|
report.HAT = HAT_TOP_RIGHT; |
||||||
|
else if ((gamecube_buttons & GAMECUBE_UP) && (gamecube_buttons & GAMECUBE_LEFT)) |
||||||
|
report.HAT = HAT_TOP_LEFT; |
||||||
|
else if ((gamecube_buttons & GAMECUBE_DOWN) && (gamecube_buttons & GAMECUBE_RIGHT)) |
||||||
|
report.HAT = HAT_BOTTOM_RIGHT; |
||||||
|
else if ((gamecube_buttons & GAMECUBE_DOWN) && (gamecube_buttons & GAMECUBE_LEFT)) |
||||||
|
report.HAT = HAT_BOTTOM_LEFT; |
||||||
|
else if (gamecube_buttons & GAMECUBE_UP) |
||||||
|
report.HAT = HAT_TOP; |
||||||
|
else if (gamecube_buttons & GAMECUBE_DOWN) |
||||||
|
report.HAT = HAT_BOTTOM; |
||||||
|
else if (gamecube_buttons & GAMECUBE_RIGHT) |
||||||
|
report.HAT = HAT_RIGHT; |
||||||
|
else if (gamecube_buttons & GAMECUBE_LEFT) |
||||||
|
report.HAT = HAT_LEFT; |
||||||
|
else |
||||||
|
report.HAT = HAT_CENTER; |
||||||
|
|
||||||
|
if (report.Button || report.HAT != HAT_CENTER) |
||||||
|
writePinHigh(C13); |
||||||
|
else |
||||||
|
writePinLow(C13); |
||||||
|
|
||||||
|
// joystick calculations
|
||||||
|
|
||||||
|
report.LX = gamecube_joysticks[0];
|
||||||
|
report.LY = 255 - gamecube_joysticks[1];
|
||||||
|
report.RX = gamecube_joysticks[2];
|
||||||
|
report.RY = 255 - gamecube_joysticks[3];
|
||||||
|
|
||||||
|
send_gamepad(&report); |
||||||
|
|
||||||
|
} |
@ -0,0 +1,47 @@ |
|||||||
|
#include "quantum.h" |
||||||
|
|
||||||
|
typedef enum { |
||||||
|
SWITCH_Y = 0x01, |
||||||
|
SWITCH_B = 0x02, |
||||||
|
SWITCH_A = 0x04, |
||||||
|
SWITCH_X = 0x08, |
||||||
|
SWITCH_L = 0x10, |
||||||
|
SWITCH_R = 0x20, |
||||||
|
SWITCH_ZL = 0x40, |
||||||
|
SWITCH_ZR = 0x80, |
||||||
|
SWITCH_MINUS = 0x100, |
||||||
|
SWITCH_PLUS = 0x200, |
||||||
|
SWITCH_LCLICK = 0x400, |
||||||
|
SWITCH_RCLICK = 0x800, |
||||||
|
SWITCH_HOME = 0x1000, |
||||||
|
SWITCH_CAPTURE = 0x2000, |
||||||
|
} SwitchButtons_t; |
||||||
|
|
||||||
|
typedef enum { |
||||||
|
GAMECUBE_A = 0b0000000000000001, |
||||||
|
GAMECUBE_B = 0b0000000000000010, |
||||||
|
GAMECUBE_X = 0b0000000000000100, |
||||||
|
GAMECUBE_Y = 0b0000000000001000, |
||||||
|
GAMECUBE_START = 0b0000000000010000, |
||||||
|
GAMECUBE_LEFT = 0b0000000100000000, |
||||||
|
GAMECUBE_RIGHT = 0b0000001000000000, |
||||||
|
GAMECUBE_DOWN = 0b0000010000000000, |
||||||
|
GAMECUBE_UP = 0b0000100000000000, |
||||||
|
GAMECUBE_Z = 0b0001000000000000, |
||||||
|
GAMECUBE_R = 0b0010000000000000, |
||||||
|
GAMECUBE_L = 0b0100000000000000, |
||||||
|
} GamecubeButtons_t; |
||||||
|
|
||||||
|
#define HAT_TOP 0x00 |
||||||
|
#define HAT_TOP_RIGHT 0x01 |
||||||
|
#define HAT_RIGHT 0x02 |
||||||
|
#define HAT_BOTTOM_RIGHT 0x03 |
||||||
|
#define HAT_BOTTOM 0x04 |
||||||
|
#define HAT_BOTTOM_LEFT 0x05 |
||||||
|
#define HAT_LEFT 0x06 |
||||||
|
#define HAT_TOP_LEFT 0x07 |
||||||
|
#define HAT_CENTER 0x08 |
||||||
|
|
||||||
|
#define STICK_MIN 0 |
||||||
|
#define STICK_CENTER 128 |
||||||
|
#define STICK_MAX 255 |
@ -0,0 +1,216 @@ |
|||||||
|
#include "gc_read.h" |
||||||
|
#include "gc_controller.h" |
||||||
|
|
||||||
|
#define CONTROLLER_TIMEOUT 60 |
||||||
|
|
||||||
|
bool init_message[9] = {0, 0, 0, 0, 0, 0, 0, 0, 1}; |
||||||
|
bool request_message[25] = { |
||||||
|
0, 1, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 1, 1,
|
||||||
|
0, 0, 0, 0, 0, 0, 1, 0, 1}; |
||||||
|
|
||||||
|
void start_message(void) { |
||||||
|
setPinOutput(GAMECUBE_DATA_PIN); |
||||||
|
writePinLow(GAMECUBE_DATA_PIN); |
||||||
|
} |
||||||
|
|
||||||
|
void send_bit(bool b) { |
||||||
|
if (b) { |
||||||
|
writePinLow(GAMECUBE_DATA_PIN); |
||||||
|
wait_ns(900); |
||||||
|
writePinHigh(GAMECUBE_DATA_PIN); |
||||||
|
wait_ns(2900); |
||||||
|
} else { |
||||||
|
writePinLow(GAMECUBE_DATA_PIN); |
||||||
|
wait_ns(2900); |
||||||
|
writePinHigh(GAMECUBE_DATA_PIN); |
||||||
|
wait_ns(900); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void wait_for_ready(void) { |
||||||
|
setPinInputHigh(GAMECUBE_DATA_PIN); |
||||||
|
|
||||||
|
// wait for long high
|
||||||
|
uint8_t ready = 0; |
||||||
|
while (ready < 5) { |
||||||
|
if (readPin(GAMECUBE_DATA_PIN)) |
||||||
|
ready++; |
||||||
|
else |
||||||
|
ready = 0; |
||||||
|
wait_us(1); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void end_message(void) { |
||||||
|
setPinInputHigh(GAMECUBE_DATA_PIN); |
||||||
|
} |
||||||
|
|
||||||
|
uint8_t buffer[9] = {0}; |
||||||
|
uint16_t buttons_debounce = 0; |
||||||
|
bool initialised = false; |
||||||
|
bool calibrated = false; |
||||||
|
uint8_t mid_values[4] = {128, 128, 128, 128}; |
||||||
|
uint8_t max_values[4] = {210, 210, 210, 210}; |
||||||
|
uint8_t min_values[4] = {35, 35, 35, 35}; |
||||||
|
|
||||||
|
void gamecube_init(void) { |
||||||
|
setPinInputHigh(GAMECUBE_DATA_PIN); |
||||||
|
} |
||||||
|
|
||||||
|
void gamecube_scan(uint16_t * buttons, uint8_t * joysticks) { |
||||||
|
bool exiting = false; |
||||||
|
uint16_t timeout_counter = 0; |
||||||
|
|
||||||
|
// somehow we're missing the first bit, which can safely be ignored
|
||||||
|
// i'm not sure if it's something with the timing or what
|
||||||
|
uint8_t buffer_bit = 1; |
||||||
|
|
||||||
|
chSysLock(); |
||||||
|
|
||||||
|
if (!initialised) { |
||||||
|
wait_for_ready(); |
||||||
|
|
||||||
|
start_message(); |
||||||
|
for (uint8_t i = 0; i < 9; i++) |
||||||
|
send_bit(init_message[i]); |
||||||
|
end_message(); |
||||||
|
|
||||||
|
initialised = true; |
||||||
|
} |
||||||
|
|
||||||
|
wait_for_ready(); |
||||||
|
|
||||||
|
start_message(); |
||||||
|
for (uint8_t i = 0; i < 25; i++) |
||||||
|
send_bit(request_message[i]); |
||||||
|
end_message(); |
||||||
|
|
||||||
|
while (!exiting) { |
||||||
|
timeout_counter = 0; |
||||||
|
// wait for low or timeout
|
||||||
|
while (readPin(GAMECUBE_DATA_PIN)) { |
||||||
|
wait_ns(100); |
||||||
|
timeout_counter++; |
||||||
|
if (timeout_counter > CONTROLLER_TIMEOUT) { |
||||||
|
exiting = true; |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if (!exiting) { |
||||||
|
// wait for the data part
|
||||||
|
wait_ns(1950); |
||||||
|
bool b = readPin(GAMECUBE_DATA_PIN); |
||||||
|
if (b) |
||||||
|
buffer[buffer_bit / 8] |= (1 << (7 - (buffer_bit % 8))); |
||||||
|
else |
||||||
|
buffer[buffer_bit / 8] &= ~(1 << (7 - (buffer_bit % 8))); |
||||||
|
buffer_bit++; |
||||||
|
|
||||||
|
// wait for high
|
||||||
|
while (!readPin(GAMECUBE_DATA_PIN)); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
chSysUnlock(); |
||||||
|
|
||||||
|
// basic debouncing for buttons
|
||||||
|
uint16_t combined_buttons = buffer[0] | (buffer[1] << 8); |
||||||
|
*buttons |= buttons_debounce & combined_buttons; |
||||||
|
*buttons &= buttons_debounce | combined_buttons; |
||||||
|
buttons_debounce = combined_buttons; |
||||||
|
|
||||||
|
if (!calibrated && mid_values[0] > 0) { |
||||||
|
mid_values[0] = buffer[2]; |
||||||
|
mid_values[1] = buffer[3]; |
||||||
|
mid_values[2] = buffer[4]; |
||||||
|
mid_values[3] = buffer[5]; |
||||||
|
calibrated = true; |
||||||
|
} |
||||||
|
|
||||||
|
if (max_values[0] < buffer[2]) |
||||||
|
max_values[0] = buffer[2]; |
||||||
|
if (max_values[1] < buffer[3]) |
||||||
|
max_values[1] = buffer[3]; |
||||||
|
if (max_values[2] < buffer[4]) |
||||||
|
max_values[2] = buffer[4]; |
||||||
|
if (max_values[3] < buffer[5]) |
||||||
|
max_values[3] = buffer[5]; |
||||||
|
|
||||||
|
if (min_values[0] > buffer[2]) |
||||||
|
min_values[0] = buffer[2]; |
||||||
|
if (min_values[1] > buffer[3]) |
||||||
|
min_values[1] = buffer[3]; |
||||||
|
if (min_values[2] > buffer[4]) |
||||||
|
min_values[2] = buffer[4]; |
||||||
|
if (min_values[3] > buffer[5]) |
||||||
|
min_values[3] = buffer[5]; |
||||||
|
|
||||||
|
// values from my GC controller in Windows
|
||||||
|
// 30 - 138 - 236
|
||||||
|
// 20 - 124 - 225
|
||||||
|
// 37 - 135 - 222
|
||||||
|
// 34 - 126 - 216
|
||||||
|
|
||||||
|
// this should be 127? i don't understand what i'm doing wrong yet
|
||||||
|
#define JOYSTICK_SCALER 180.0 |
||||||
|
|
||||||
|
int32_t lx_temp = (int16_t)buffer[2] - mid_values[0]; |
||||||
|
if (lx_temp > 0) |
||||||
|
lx_temp *= JOYSTICK_SCALER / (max_values[0]-mid_values[0]); |
||||||
|
else |
||||||
|
lx_temp *= JOYSTICK_SCALER / (mid_values[0]-min_values[0]); |
||||||
|
lx_temp += STICK_CENTER; |
||||||
|
if (lx_temp > 255) |
||||||
|
lx_temp = 255; |
||||||
|
if (lx_temp < 0) |
||||||
|
lx_temp = 0; |
||||||
|
|
||||||
|
int32_t ly_temp = (int16_t)buffer[3] - mid_values[1]; |
||||||
|
if (ly_temp > 0) |
||||||
|
ly_temp *= JOYSTICK_SCALER / (max_values[1]-mid_values[1]); |
||||||
|
else |
||||||
|
ly_temp *= JOYSTICK_SCALER / (mid_values[1]-min_values[1]); |
||||||
|
ly_temp += STICK_CENTER; |
||||||
|
if (ly_temp > 255) |
||||||
|
ly_temp = 255; |
||||||
|
if (ly_temp < 0) |
||||||
|
ly_temp = 0; |
||||||
|
|
||||||
|
int32_t rx_temp = (int16_t)buffer[4] - mid_values[2]; |
||||||
|
if (rx_temp > 0) |
||||||
|
rx_temp *= JOYSTICK_SCALER / (max_values[2]-mid_values[2]); |
||||||
|
else |
||||||
|
rx_temp *= JOYSTICK_SCALER / (mid_values[2]-min_values[2]); |
||||||
|
rx_temp += STICK_CENTER; |
||||||
|
if (rx_temp > 255) |
||||||
|
rx_temp = 255; |
||||||
|
if (rx_temp < 0) |
||||||
|
rx_temp = 0; |
||||||
|
|
||||||
|
int32_t ry_temp = (int16_t)buffer[5] - mid_values[3]; |
||||||
|
if (ry_temp > 0) |
||||||
|
ry_temp *= JOYSTICK_SCALER / (max_values[3]-mid_values[3]); |
||||||
|
else |
||||||
|
ry_temp *= JOYSTICK_SCALER / (mid_values[3]-min_values[3]); |
||||||
|
ry_temp += STICK_CENTER; |
||||||
|
if (ry_temp > 255) |
||||||
|
ry_temp = 255; |
||||||
|
if (ry_temp < 0) |
||||||
|
ry_temp = 0; |
||||||
|
|
||||||
|
// checks to avoid a data skip (0 values on input, which aren't possible, i think)
|
||||||
|
if (buffer[2]) |
||||||
|
joysticks[0] = lx_temp; |
||||||
|
if (buffer[3]) |
||||||
|
joysticks[1] = ly_temp; |
||||||
|
if (buffer[4]) |
||||||
|
joysticks[2] = rx_temp; |
||||||
|
if (buffer[5]) |
||||||
|
joysticks[3] = ry_temp; |
||||||
|
if (buffer[6]) |
||||||
|
joysticks[4] = buffer[6]; |
||||||
|
if (buffer[7]) |
||||||
|
joysticks[5] = buffer[7]; |
||||||
|
} |
@ -0,0 +1,34 @@ |
|||||||
|
#include "quantum.h" |
||||||
|
|
||||||
|
/* Adapted from https://github.com/bigjosh/SimpleNeoPixelDemo/ */ |
||||||
|
|
||||||
|
#ifndef NOP_FUDGE |
||||||
|
# if defined(STM32F0XX) || defined(STM32F1XX) || defined(STM32F3XX) || defined(STM32F4XX) || defined(STM32L0XX) |
||||||
|
# define NOP_FUDGE 0.4 |
||||||
|
# else |
||||||
|
# error("NOP_FUDGE configuration required") |
||||||
|
# define NOP_FUDGE 1 // this just pleases the compile so the above error is easier to spot
|
||||||
|
# endif |
||||||
|
#endif |
||||||
|
|
||||||
|
#define NUMBER_NOPS 6 |
||||||
|
#define CYCLES_PER_SEC (STM32_SYSCLK / NUMBER_NOPS * NOP_FUDGE) |
||||||
|
#define NS_PER_SEC (1000000000L) // Note that this has to be SIGNED since we want to be able to check for negative values of derivatives
|
||||||
|
#define NS_PER_CYCLE (NS_PER_SEC / CYCLES_PER_SEC) |
||||||
|
#define NS_TO_CYCLES(n) ((n) / NS_PER_CYCLE) |
||||||
|
|
||||||
|
#define wait_ns(x) \ |
||||||
|
do { \
|
||||||
|
for (int i = 0; i < NS_TO_CYCLES(x); i++) { \
|
||||||
|
__asm__ volatile("nop\n\t" \
|
||||||
|
"nop\n\t" \
|
||||||
|
"nop\n\t" \
|
||||||
|
"nop\n\t" \
|
||||||
|
"nop\n\t" \
|
||||||
|
"nop\n\t"); \
|
||||||
|
} \
|
||||||
|
} while (0) |
||||||
|
|
||||||
|
|
||||||
|
void gamecube_init(void); |
||||||
|
void gamecube_scan(uint16_t * buttons, uint8_t * joysticks); |
@ -0,0 +1,3 @@ |
|||||||
|
#include QMK_KEYBOARD_H |
||||||
|
|
||||||
|
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { { { 0 } } }; |
@ -0,0 +1,12 @@ |
|||||||
|
|
||||||
|
J1 header |
||||||
|
--------- |
||||||
|
|
||||||
|
|#|Color |Proton C|Description| |
||||||
|
|-|-------|----|------------| |
||||||
|
|1|blue |3.3V| | |
||||||
|
|2|yellow |5V | | |
||||||
|
|3|red |A2 |Data (3.3V) | |
||||||
|
|4|green |GND | | |
||||||
|
|5|white |GND | | |
||||||
|
|6|black |NC | | |
@ -0,0 +1,15 @@ |
|||||||
|
# MCU name
|
||||||
|
MCU = STM32F303
|
||||||
|
|
||||||
|
BACKLIGHT_ENABLE = no
|
||||||
|
MOUSEKEY_ENABLE = no
|
||||||
|
EXTRAKEY_ENABLE = no
|
||||||
|
CONSOLE_ENABLE = no
|
||||||
|
NKRO_ENABLE = no
|
||||||
|
RAW_ENABLE = no
|
||||||
|
MIDI_ENABLE = no
|
||||||
|
VIRTSER_ENABLE = no
|
||||||
|
KEYBOARD_ENABLE = no
|
||||||
|
SWITCH_CONTROLLER_ENABLE = yes
|
||||||
|
|
||||||
|
SRC += gc_read.c
|
@ -0,0 +1,4 @@ |
|||||||
|
#pragma once |
||||||
|
|
||||||
|
void send_gamepad(report_gamepad_t *report); |
||||||
|
void gamepad_ep_task(void); |
Loading…
Reference in new issue