diff --git a/src/controller_config.h b/src/controller_config.h index 47dfbc6..394e029 100644 --- a/src/controller_config.h +++ b/src/controller_config.h @@ -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 diff --git a/src/pico_game_controller.c b/src/pico_game_controller.c index 11d7e16..b4451ff 100644 --- a/src/pico_game_controller.c +++ b/src/pico_game_controller.c @@ -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; diff --git a/src/usb_descriptors.c b/src/usb_descriptors.c index 0c0aaaa..954445d 100644 --- a/src/usb_descriptors.c +++ b/src/usb_descriptors.c @@ -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]; diff --git a/src/usb_descriptors.h b/src/usb_descriptors.h index d9b601c..7900edf 100644 --- a/src/usb_descriptors.h +++ b/src/usb_descriptors.h @@ -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), \