This commit is contained in:
Nicholas G
2022-04-05 22:01:20 -04:00
parent 5745a4ae17
commit 7cc2d59373
4 changed files with 124 additions and 74 deletions
+32 -11
View File
@@ -2,7 +2,6 @@
#define CONTROLLER_CONFIG_H
#define SW_GPIO_SIZE 9 // Number of switches
#define LED_GPIO_SIZE 7 // Number of switch LEDs
#define ENC_GPIO_SIZE 2 // Number of encoders
#define ENC_PPR 24 // Encoder PPR
#define MOUSE_SENS 5 // Mouse sensitivity multiplier
@@ -10,27 +9,49 @@
#define SW_DEBOUNCE_TIME_US 4000 // Switch debounce delay in us
#define ENC_PULSE (ENC_PPR * 4) // 4 pulses per PPR
#define REACTIVE_TIMEOUT_MAX 1000000 // HID to reactive timeout in us
#define WS2812B_LED_SIZE 10 // Number of WS2812B LEDs
#define WS2812B_LED_ZONES 2 // Number of WS2812B LED Zones
#define WS2812B_LEDS_PER_ZONE \
WS2812B_LED_SIZE / WS2812B_LED_ZONES // Number of LEDs per zone
#define WS2812B_LED_SIZE 32 // Number of WS2812B LEDs
#define WS2812B_LED_ZONES 1 // Number of WS2812B LED Zones
#ifdef PICO_GAME_CONTROLLER_C
typedef struct {
uint8_t r, g, b;
} RGB_t;
const RGB_t COLOR_BLACK = {0, 0, 0};
const RGB_t SW_LABEL_COLORS[] = {
{255, 255, 255}, // START
{255, 255, 255}, // BT-A
{255, 255, 255}, // BT-B
{255, 255, 255}, // BT-C
{255, 255, 255}, // BT-D
{255, 255, 255}, // FX-L
{255, 255, 255}, // FX-R
};
const RGB_t SW_COLORS[] = {
{0, 0, 255}, // START
{255, 255, 255}, // BT-A
{255, 255, 255}, // BT-B
{255, 255, 255}, // BT-C
{255, 255, 255}, // BT-D
{255, 0, 0}, // FX-L
{255, 0, 0}, // FX-R
};
// MODIFY KEYBINDS HERE, MAKE SURE LENGTHS MATCH SW_GPIO_SIZE
const uint8_t SW_KEYCODE[] = {
HID_KEY_D, HID_KEY_F, HID_KEY_J, HID_KEY_K, HID_KEY_C,
HID_KEY_M, HID_KEY_A, HID_KEY_B, HID_KEY_1,
};
const uint8_t SW_GPIO[] = {
4, 6, 8, 10, 12, 14, 27, 18, 20,
29, 3, 4, 5, 17, 12, 0, 8, 1,
};
const uint8_t LED_GPIO[] = {
5, 7, 9, 11, 13, 15, 21,
};
const uint8_t ENC_GPIO[] = {0, 2}; // L_ENC(0, 1); R_ENC(2, 3)
const uint8_t ENC_GPIO[] = {27, 6}; // L_ENC(0, 1); R_ENC(2, 3)
const bool ENC_REV[] = {false, false}; // Reverse Encoders
const uint8_t WS2812B_GPIO = 28;
const uint8_t WS2812B_GPIO = 2;
#endif
+87 -56
View File
@@ -36,16 +36,14 @@ uint64_t reactive_timeout_timestamp;
void (*loop_mode)();
bool joy_mode_check = true;
typedef struct {
uint8_t r, g, b;
} RGB_t;
RGB_t ws2812b_data[32] = {0};
union {
struct {
uint8_t buttons[LED_GPIO_SIZE];
uint8_t buttons[SW_GPIO_SIZE];
RGB_t rgb[WS2812B_LED_ZONES];
} lights;
uint8_t raw[LED_GPIO_SIZE + WS2812B_LED_ZONES * 3];
uint8_t raw[SW_GPIO_SIZE + WS2812B_LED_ZONES * 3];
} lights_report;
/**
@@ -67,16 +65,37 @@ static inline uint32_t urgb_u32(uint8_t r, uint8_t g, uint8_t b) {
* 768 Color Wheel Picker
* @param wheel_pos Color value, r->g->b->r...
**/
uint32_t color_wheel(uint16_t wheel_pos) {
RGB_t color_wheel(uint16_t wheel_pos) {
RGB_t temp = {0, 0, 0};
wheel_pos %= 768;
if (wheel_pos < 256) {
return urgb_u32(wheel_pos, 255 - wheel_pos, 0);
temp.r = wheel_pos;
temp.g = 255 - wheel_pos;
temp.b = 0;
return temp;
} else if (wheel_pos < 512) {
wheel_pos -= 256;
return urgb_u32(255 - wheel_pos, 0, wheel_pos);
temp.r = 255 - wheel_pos;
temp.g = 0;
temp.b = wheel_pos;
return temp;
} else {
wheel_pos -= 512;
return urgb_u32(0, wheel_pos, 255 - wheel_pos);
temp.r = 0;
temp.g = wheel_pos;
temp.b = 255 - wheel_pos;
return temp;
}
}
/**
* Color rainbow effect
**/
void ws2812b_color_rainbow(uint32_t counter) {
for (int i = (SW_GPIO_SIZE - 2) * 2; i < WS2812B_LED_SIZE; i++) {
ws2812b_data[i] = color_wheel(
(counter + i * (int)(768 / (WS2812B_LED_SIZE - SW_GPIO_SIZE * 2))) %
768);
}
}
@@ -84,61 +103,76 @@ uint32_t color_wheel(uint16_t wheel_pos) {
* Color cycle effect
**/
void ws2812b_color_cycle(uint32_t counter) {
for (int i = 0; i < WS2812B_LED_SIZE; ++i) {
put_pixel(color_wheel((counter + i * (int)(768 / WS2812B_LED_SIZE)) % 768));
for (int i = (SW_GPIO_SIZE - 2) * 2; i < WS2812B_LED_SIZE; i++) {
ws2812b_data[i] = color_wheel(counter % 768);
}
}
/**
* WS2812B Lighting
* HID/Reactive Button Lights
* @param counter Current number of WS2812B cycles
**/
void ws2812b_update(uint32_t counter) {
if (time_us_64() - reactive_timeout_timestamp >= REACTIVE_TIMEOUT_MAX) {
ws2812b_color_cycle(counter);
} else {
for (int i = 0; i < WS2812B_LED_ZONES; i++) {
for (int j = 0; j < WS2812B_LEDS_PER_ZONE; j++) {
put_pixel(urgb_u32(lights_report.lights.rgb[i].r,
lights_report.lights.rgb[i].g,
lights_report.lights.rgb[i].b));
}
}
}
}
/**
* HID/Reactive Lights
**/
void update_lights() {
for (int i = 0; i < LED_GPIO_SIZE - 1; i++) {
void update_button_lights() {
/* Switches */
for (int i = 0; i < SW_GPIO_SIZE - 3; i++) {
if (time_us_64() - reactive_timeout_timestamp >= REACTIVE_TIMEOUT_MAX) {
if (!gpio_get(SW_GPIO[i])) {
gpio_put(LED_GPIO[i], 1);
ws2812b_data[2 * i + 2] = SW_COLORS[i + 1];
} else {
gpio_put(LED_GPIO[i], 0);
ws2812b_data[2 * i + 2] = COLOR_BLACK;
}
} else {
if (lights_report.lights.buttons[i] == 0) {
gpio_put(LED_GPIO[i], 0);
ws2812b_data[2 * i + 2] = COLOR_BLACK;
} else {
gpio_put(LED_GPIO[i], 1);
ws2812b_data[2 * i + 2] = SW_COLORS[i + 1];
}
}
/* start button sw_val index is offset by two with respect to LED_GPIO */
if (time_us_64() - reactive_timeout_timestamp >= REACTIVE_TIMEOUT_MAX) {
if (!gpio_get(SW_GPIO[LED_GPIO_SIZE + 1])) {
gpio_put(LED_GPIO[LED_GPIO_SIZE - 1], 1);
} else {
gpio_put(LED_GPIO[LED_GPIO_SIZE - 1], 0);
}
}
/* start button sw_val index is offset by two with respect to LED_GPIO */
if (time_us_64() - reactive_timeout_timestamp >= REACTIVE_TIMEOUT_MAX) {
if (!gpio_get(SW_GPIO[SW_GPIO_SIZE - 1])) {
ws2812b_data[0] = SW_COLORS[0];
} else {
if (lights_report.lights.buttons[LED_GPIO_SIZE - 1] == 0) {
gpio_put(LED_GPIO[LED_GPIO_SIZE - 1], 0);
} else {
gpio_put(LED_GPIO[LED_GPIO_SIZE - 1], 1);
}
ws2812b_data[0] = COLOR_BLACK;
}
} else {
if (lights_report.lights.buttons[SW_GPIO_SIZE - 1] == 0) {
ws2812b_data[0] = COLOR_BLACK;
} else {
ws2812b_data[0] = SW_COLORS[0];
}
}
/* Switch Labels */
for (int i = 0; i < SW_GPIO_SIZE - 2; i++) {
ws2812b_data[2 * i + 1] = SW_LABEL_COLORS[i];
}
}
/**
* HID/Reactive Peripheral Lights
* @param counter Current RGB color
**/
void update_peripheral_lights(uint32_t counter) {
/* Peripheral RGB */
if (time_us_64() - reactive_timeout_timestamp >= REACTIVE_TIMEOUT_MAX) {
ws2812b_color_cycle(counter);
} else {
for (int i = SW_GPIO_SIZE * 2; i < WS2812B_LED_SIZE; i++) {
ws2812b_data[i].r = lights_report.lights.rgb[i].r;
ws2812b_data[i].g = lights_report.lights.rgb[i].g;
ws2812b_data[i].b = lights_report.lights.rgb[i].b;
}
}
}
/**
* WS2812B Lighting Updated from ws2812b_data
**/
void ws2812b_update() {
for (int i = 0; i < WS2812B_LED_SIZE; i++) {
put_pixel(
urgb_u32(ws2812b_data[i].r, ws2812b_data[i].g, ws2812b_data[i].b));
}
}
@@ -259,9 +293,13 @@ void dma_handler() {
**/
void core1_entry() {
uint32_t counter = 0;
uint32_t rgb_idx = 0;
while (1) {
ws2812b_update(++counter);
sleep_ms(5);
counter++;
if (counter % 10 == 0) update_peripheral_lights(++rgb_idx);
update_button_lights();
ws2812b_update();
sleep_ms(1);
}
}
@@ -317,12 +355,6 @@ void init() {
gpio_pull_up(SW_GPIO[i]);
}
// Setup LED GPIO
for (int i = 0; i < LED_GPIO_SIZE; i++) {
gpio_init(LED_GPIO[i]);
gpio_set_dir(LED_GPIO[i], GPIO_OUT);
}
// Set listener bools
kbm_report = false;
@@ -353,7 +385,6 @@ int main(void) {
tud_task(); // tinyusb device task
update_inputs();
loop_mode();
update_lights();
}
return 0;
+3 -6
View File
@@ -162,12 +162,9 @@ char const* string_desc_arr[] = {
"FX-L",
"FX-R",
"Start",
"Left R",
"Left G",
"Left B",
"Right R",
"Right G",
"Right B",
"Controller R",
"Controller G",
"Controller B",
};
static uint16_t _desc_str[64];
+2 -1
View File
@@ -42,7 +42,8 @@ enum {
#define GAMECON_REPORT_DESC_LIGHTS(...) \
HID_USAGE_PAGE(HID_USAGE_PAGE_DESKTOP), HID_USAGE(0x00), \
HID_COLLECTION(HID_COLLECTION_APPLICATION), \
__VA_ARGS__ HID_REPORT_COUNT(LED_GPIO_SIZE + (WS2812B_LED_ZONES * 3)), \
__VA_ARGS__ HID_REPORT_COUNT(SW_GPIO_SIZE - 2 + \
(WS2812B_LED_ZONES * 3)), \
HID_REPORT_SIZE(8), HID_LOGICAL_MIN(0x00), HID_LOGICAL_MAX_N(0x00ff, 2), \
HID_USAGE_PAGE(HID_USAGE_PAGE_ORDINAL), HID_STRING_MINIMUM(4), \
HID_STRING_MAXIMUM(16), HID_USAGE_MIN(1), HID_USAGE_MAX(13), \