From c6567d0b9b939ab8fd892d5bb481c778803e87bb Mon Sep 17 00:00:00 2001 From: Nicholas Gadjali Date: Mon, 4 Jul 2022 02:42:46 -0700 Subject: [PATCH] RGB Refactor Cleanup, turbocharger mode from 4yn --- build_uf2/Pico_Game_Controller.uf2 | Bin 74240 -> 76800 bytes src/controller_config.h | 2 +- src/pico_game_controller.c | 59 +++------------ src/rgb/color_cycle.c | 9 +++ src/rgb/rgb_include.h | 10 +++ src/rgb/turbocharger.c | 111 +++++++++++++++++++++++++++++ src/rgb/ws2812b_util.c | 41 +++++++++++ 7 files changed, 183 insertions(+), 49 deletions(-) create mode 100644 src/rgb/color_cycle.c create mode 100644 src/rgb/rgb_include.h create mode 100644 src/rgb/turbocharger.c create mode 100644 src/rgb/ws2812b_util.c diff --git a/build_uf2/Pico_Game_Controller.uf2 b/build_uf2/Pico_Game_Controller.uf2 index c97b943cda61dde7dafe9341061fa1750157c790..5b0abf8ee8099fed32a2d13f764d76462adc3eeb 100644 GIT binary patch delta 13397 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

!lwg)Eo8x-;v%H` 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 delta 11960 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... - **/ -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); diff --git a/src/rgb/color_cycle.c b/src/rgb/color_cycle.c new file mode 100644 index 0000000..e5708b6 --- /dev/null +++ b/src/rgb/color_cycle.c @@ -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)); + } +} \ No newline at end of file diff --git a/src/rgb/rgb_include.h b/src/rgb/rgb_include.h new file mode 100644 index 0000000..02d2264 --- /dev/null +++ b/src/rgb/rgb_include.h @@ -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" \ No newline at end of file diff --git a/src/rgb/turbocharger.c b/src/rgb/turbocharger.c new file mode 100644 index 0000000..81f2dec --- /dev/null +++ b/src/rgb/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) + )); + } +} diff --git a/src/rgb/ws2812b_util.c b/src/rgb/ws2812b_util.c new file mode 100644 index 0000000..aae7f18 --- /dev/null +++ b/src/rgb/ws2812b_util.c @@ -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); +} \ No newline at end of file