mirror of
https://github.com/speedypotato/Pico-Game-Controller.git
synced 2026-10-01 11:17:56 +03:00
RGB Refactor Cleanup, turbocharger mode from 4yn
This commit is contained in:
Binary file not shown.
@@ -6,7 +6,7 @@
|
||||
#define ENC_GPIO_SIZE 2 // Number of encoders
|
||||
#define ENC_PPR 600 // Encoder PPR
|
||||
#define MOUSE_SENS 1 // Mouse sensitivity multiplier
|
||||
#define ENC_DEBOUNCE true // Encoder Debouncing
|
||||
#define ENC_DEBOUNCE false // Encoder Debouncing
|
||||
#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
|
||||
|
||||
+11
-48
@@ -17,9 +17,9 @@
|
||||
#include "hardware/pio.h"
|
||||
#include "pico/multicore.h"
|
||||
#include "pico/stdlib.h"
|
||||
#include "rgb/rgb_include.h"
|
||||
#include "tusb.h"
|
||||
#include "usb_descriptors.h"
|
||||
#include "ws2812.pio.h"
|
||||
|
||||
PIO pio, pio_1;
|
||||
uint32_t enc_val[ENC_GPIO_SIZE];
|
||||
@@ -33,13 +33,10 @@ bool kbm_report;
|
||||
|
||||
uint64_t reactive_timeout_timestamp;
|
||||
|
||||
void (*ws2812b_mode)();
|
||||
void (*loop_mode)();
|
||||
bool joy_mode_check = true;
|
||||
|
||||
typedef struct {
|
||||
uint8_t r, g, b;
|
||||
} RGB_t;
|
||||
|
||||
union {
|
||||
struct {
|
||||
uint8_t buttons[LED_GPIO_SIZE];
|
||||
@@ -48,54 +45,13 @@ union {
|
||||
uint8_t raw[LED_GPIO_SIZE + WS2812B_LED_ZONES * 3];
|
||||
} lights_report;
|
||||
|
||||
/**
|
||||
* WS2812B RGB Assignment
|
||||
* @param pixel_grb The pixel color to set
|
||||
**/
|
||||
static inline void put_pixel(uint32_t pixel_grb) {
|
||||
pio_sm_put_blocking(pio1, ENC_GPIO_SIZE, pixel_grb << 8u);
|
||||
}
|
||||
|
||||
/**
|
||||
* WS2812B RGB Format Helper
|
||||
**/
|
||||
static inline uint32_t urgb_u32(uint8_t r, uint8_t g, uint8_t b) {
|
||||
return ((uint32_t)(r) << 8) | ((uint32_t)(g) << 16) | (uint32_t)(b);
|
||||
}
|
||||
|
||||
/**
|
||||
* 768 Color Wheel Picker
|
||||
* @param wheel_pos Color value, r->g->b->r...
|
||||
**/
|
||||
uint32_t color_wheel(uint16_t wheel_pos) {
|
||||
wheel_pos %= 768;
|
||||
if (wheel_pos < 256) {
|
||||
return urgb_u32(wheel_pos, 255 - wheel_pos, 0);
|
||||
} else if (wheel_pos < 512) {
|
||||
wheel_pos -= 256;
|
||||
return urgb_u32(255 - wheel_pos, 0, wheel_pos);
|
||||
} else {
|
||||
wheel_pos -= 512;
|
||||
return urgb_u32(0, wheel_pos, 255 - 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));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* WS2812B Lighting
|
||||
* @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);
|
||||
ws2812b_mode(counter);
|
||||
} else {
|
||||
for (int i = 0; i < WS2812B_LED_ZONES; i++) {
|
||||
for (int j = 0; j < WS2812B_LEDS_PER_ZONE; j++) {
|
||||
@@ -275,7 +231,7 @@ void init() {
|
||||
channel_config_set_dreq(&c, pio_get_dreq(pio, i, false));
|
||||
|
||||
dma_channel_configure(i, &c,
|
||||
&enc_val[i], // Destinatinon pointer
|
||||
&enc_val[i], // Destination pointer
|
||||
&pio->rxf[i], // Source pointer
|
||||
0x10, // Number of transfers
|
||||
true // Start immediately
|
||||
@@ -321,6 +277,13 @@ void init() {
|
||||
joy_mode_check = true;
|
||||
}
|
||||
|
||||
// RGB Mode Switching
|
||||
if (!gpio_get(SW_GPIO[1])) {
|
||||
ws2812b_mode = &turbocharger_color_cycle;
|
||||
} else {
|
||||
ws2812b_mode = &ws2812b_color_cycle;
|
||||
}
|
||||
|
||||
// Disable RGB
|
||||
if (gpio_get(SW_GPIO[8])) {
|
||||
multicore_launch_core1(core1_entry);
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
/**
|
||||
* Color cycle effect
|
||||
* @author SpeedyPotato
|
||||
**/
|
||||
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));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* Simple header file to include all files in the folder
|
||||
* @author SpeedyPotato
|
||||
*
|
||||
* To add a lighting mode, create a function which accepts a uint32_t as a parameter.
|
||||
* Create lighting mode as desired and then add the #include here.
|
||||
**/
|
||||
#include "ws2812b_util.c"
|
||||
#include "color_cycle.c"
|
||||
#include "turbocharger.c"
|
||||
@@ -0,0 +1,111 @@
|
||||
/**
|
||||
* @author 4yn, SpeedyPotato
|
||||
* Turbocharger chasing laser effect
|
||||
*
|
||||
* Move 2 lighting areas around the controller depending on knob input.
|
||||
*
|
||||
* For each knob, calculate every 5 ms:
|
||||
* - Add any knob delta to a counter
|
||||
* - Clamp counter to some "maximum speed"
|
||||
* - If counter is far enough from 0, knob is moving
|
||||
* - If counter is too near 0 and has been there for a while, fade out
|
||||
* - Move the lighting area in the correct direction at a constant speed
|
||||
* - Decay the counter
|
||||
*
|
||||
* Curent values are tuned for
|
||||
* - Lights sampled at 200 Hz
|
||||
* - 0.1 rotations for lights to activate
|
||||
* - Lighting areas take 0.75s to make one full rotation
|
||||
* - Movement takes 0.5s to decay to stop
|
||||
* - Fade out takes another 0.2s samples to disappear
|
||||
*
|
||||
* LEDs are positioned as:
|
||||
* - 0, 1 as dummy leds on top of controller
|
||||
* - 2-6 LEDs on right edge, top to bottom
|
||||
* - 7-9 as dummy leds on bottom of controller
|
||||
* - 10-14 LEDs on left edge, bottom to top
|
||||
* - 15 as dummy led on top of controller
|
||||
*
|
||||
* Lighting areas start at position 0 and will light up the 3 nearest LEDs.
|
||||
* By strategically positioning led 0 at the top, this avoids lighting areas
|
||||
* from suddenly appeaering.
|
||||
**/
|
||||
extern uint32_t enc_val[ENC_GPIO_SIZE];
|
||||
|
||||
#define TURBO_LIGHTS_CLAMP 0.1f
|
||||
#define TURBO_LIGHTS_THRESHOLD 0.05f
|
||||
#define TURBO_LIGHTS_DECAY 0.0005f
|
||||
#define TURBO_LIGHTS_VEL 0.12f
|
||||
#define TURBO_LIGHTS_MAX (WS2812B_LED_SIZE + 6.0f)
|
||||
#define TURBO_LIGHTS_FADE 40
|
||||
#define TURBO_LIGHTS_FADE_VEL 0.025f
|
||||
|
||||
int i_clamp(int d, int min, int max) {
|
||||
const int t = d < min ? min : d;
|
||||
return t > max ? max : t;
|
||||
}
|
||||
|
||||
float f_clamp(float d, float min, float max) {
|
||||
const float t = d < min ? min : d;
|
||||
return t > max ? max : t;
|
||||
}
|
||||
|
||||
float f_one_mod(float d, float mod) {
|
||||
const float t = d < 0 ? d + mod : d;
|
||||
return t > mod ? t - mod : t;
|
||||
}
|
||||
|
||||
float f_abs(float d) {
|
||||
return d < 0 ? -d : d;
|
||||
}
|
||||
|
||||
uint32_t turbo_prev_enc_val[ENC_GPIO_SIZE];
|
||||
float turbo_cur_enc_val[ENC_GPIO_SIZE];
|
||||
float turbo_lights_pos[ENC_GPIO_SIZE];
|
||||
float turbo_lights_brightness[ENC_GPIO_SIZE];
|
||||
int turbo_lights_idle[ENC_GPIO_SIZE];
|
||||
|
||||
void turbocharger_color_cycle(uint32_t unused) {
|
||||
for (int i = 0; i < ENC_GPIO_SIZE; i++) {
|
||||
int enc_delta = (enc_val[i] - turbo_prev_enc_val[i]) * (ENC_REV[i] ? 1 : -1);
|
||||
turbo_prev_enc_val[i] = enc_val[i];
|
||||
turbo_cur_enc_val[i] = f_clamp(turbo_cur_enc_val[i] + (float)(enc_delta) / ENC_PULSE, -TURBO_LIGHTS_CLAMP, TURBO_LIGHTS_CLAMP);
|
||||
|
||||
if (turbo_cur_enc_val[i] < -TURBO_LIGHTS_THRESHOLD) {
|
||||
turbo_lights_idle[i] = 0;
|
||||
turbo_lights_pos[i] += TURBO_LIGHTS_VEL;
|
||||
turbo_lights_brightness[i] = 1.0f;
|
||||
} else if (turbo_cur_enc_val[i] > TURBO_LIGHTS_THRESHOLD) {
|
||||
turbo_lights_idle[i] = 0;
|
||||
turbo_lights_pos[i] -= TURBO_LIGHTS_VEL;
|
||||
turbo_lights_brightness[i] = 1.0f;
|
||||
} else {
|
||||
turbo_lights_idle[i]++;
|
||||
if (turbo_lights_idle[i] > TURBO_LIGHTS_FADE) {
|
||||
turbo_lights_pos[i] = 0;
|
||||
} else {
|
||||
turbo_lights_brightness[i] = f_clamp(turbo_lights_brightness[i] - TURBO_LIGHTS_FADE_VEL, 0.0f, 1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
turbo_lights_pos[i] = f_one_mod(turbo_lights_pos[i], TURBO_LIGHTS_MAX);
|
||||
|
||||
if (turbo_cur_enc_val[i] < -TURBO_LIGHTS_DECAY) {
|
||||
turbo_cur_enc_val[i] += TURBO_LIGHTS_DECAY;
|
||||
} else if (turbo_cur_enc_val[i] > TURBO_LIGHTS_DECAY) {
|
||||
turbo_cur_enc_val[i] -= TURBO_LIGHTS_DECAY;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < WS2812B_LED_SIZE; i++) {
|
||||
float pos = 2.0f + i + (i >= WS2812B_LED_SIZE / 2 ? 3.0f : 0.0f);
|
||||
float l_strength = (1.0f - f_clamp(f_abs(turbo_lights_pos[0] - pos), 0.0f, 2.0f) / 2) * turbo_lights_brightness[0];
|
||||
float r_strength = (1.0f - f_clamp(f_abs(turbo_lights_pos[1] - pos), 0.0f, 2.0f) / 2) * turbo_lights_brightness[1];
|
||||
|
||||
put_pixel(urgb_u32(
|
||||
i_clamp(l_strength * 70 + r_strength * 250, 0, 255),
|
||||
i_clamp(l_strength * 230 + r_strength * 60, 0, 255),
|
||||
i_clamp(l_strength * 250 + r_strength * 200, 0, 255)
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* ws2812b utility class
|
||||
* @author SpeedyPotato
|
||||
*/
|
||||
#include "ws2812.pio.h"
|
||||
|
||||
typedef struct {
|
||||
uint8_t r, g, b;
|
||||
} RGB_t;
|
||||
|
||||
/**
|
||||
* WS2812B RGB Format Helper
|
||||
**/
|
||||
static inline uint32_t urgb_u32(uint8_t r, uint8_t g, uint8_t b) {
|
||||
return ((uint32_t)(r) << 8) | ((uint32_t)(g) << 16) | (uint32_t)(b);
|
||||
}
|
||||
|
||||
/**
|
||||
* 768 Color Wheel Picker
|
||||
* @param wheel_pos Color value, r->g->b->r...
|
||||
**/
|
||||
static inline uint32_t color_wheel(uint16_t wheel_pos) {
|
||||
wheel_pos %= 768;
|
||||
if (wheel_pos < 256) {
|
||||
return urgb_u32(wheel_pos, 255 - wheel_pos, 0);
|
||||
} else if (wheel_pos < 512) {
|
||||
wheel_pos -= 256;
|
||||
return urgb_u32(255 - wheel_pos, 0, wheel_pos);
|
||||
} else {
|
||||
wheel_pos -= 512;
|
||||
return urgb_u32(0, wheel_pos, 255 - wheel_pos);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* WS2812B RGB Assignment
|
||||
* @param pixel_grb The pixel color to set
|
||||
**/
|
||||
static inline void put_pixel(uint32_t pixel_grb) {
|
||||
pio_sm_put_blocking(pio1, ENC_GPIO_SIZE, pixel_grb << 8u);
|
||||
}
|
||||
Reference in New Issue
Block a user