diff options
author | Fred Sundvik <fsundvik@gmail.com> | 2017-04-02 01:31:04 +0300 |
---|---|---|
committer | Fred Sundvik <fsundvik@gmail.com> | 2017-04-09 18:34:59 +0300 |
commit | 39385144e7dc3337e623cdc8147b4a441f22fd62 (patch) | |
tree | c553b85bbd7c0754296f999e83647ac7b779a22d /keyboards/ergodox/infinity/visualizer.c | |
parent | 9a4ce28683b667ab67d48d92196bab7e277d4800 (diff) |
Emulate Ergodox EZ leds by LCD colors
Diffstat (limited to 'keyboards/ergodox/infinity/visualizer.c')
-rw-r--r-- | keyboards/ergodox/infinity/visualizer.c | 175 |
1 files changed, 165 insertions, 10 deletions
diff --git a/keyboards/ergodox/infinity/visualizer.c b/keyboards/ergodox/infinity/visualizer.c index 6af3a72ee1..7bc42fbc70 100644 --- a/keyboards/ergodox/infinity/visualizer.c +++ b/keyboards/ergodox/infinity/visualizer.c @@ -27,6 +27,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. #endif #include "visualizer.h" +#include "system/serial_link.h" // To generate an image array like this // Ensure the image is 128 x 32 or smaller @@ -73,6 +74,15 @@ static const uint8_t image_data_lcd_logo[512] = { static const uint32_t logo_background_color = LCD_COLOR(0x00, 0x00, 0xFF); static const uint32_t initial_color = LCD_COLOR(0, 0, 0); +static const uint32_t led_emulation_colors[4] = { + LCD_COLOR(0, 0, 0), + LCD_COLOR(255, 255, 255), + LCD_COLOR(84, 255, 255), + LCD_COLOR(168, 255, 255), +}; + +static uint32_t next_led_target_color = 0; + typedef enum { LCD_STATE_INITIAL, LCD_STATE_LAYER_BITMAP, @@ -81,6 +91,19 @@ typedef enum { static lcd_state_t lcd_state = LCD_STATE_INITIAL; +typedef struct { + uint8_t led_on; + uint8_t led1; + uint8_t led2; + uint8_t led3; +} visualizer_user_data_t; + +// Don't access from visualization function, use the visualizer state instead +static visualizer_user_data_t user_data_keyboard = {}; + +_Static_assert(sizeof(visualizer_user_data_t) <= VISUALIZER_USER_DATA_SIZE, + "Please increase the VISUALIZER_USER_DATA_SIZE"); + bool display_logo(keyframe_animation_t* animation, visualizer_state_t* state) { (void)state; (void)animation; @@ -117,16 +140,27 @@ static keyframe_animation_t startup_animation = { }; // The color animation animates the LCD color when you change layers -static keyframe_animation_t color_animation = { - .num_frames = 2, +static keyframe_animation_t one_led_color = { + .num_frames = 1, .loop = false, - // Note that there's a 200 ms no-operation frame, - // this prevents the color from changing when activating the layer - // momentarily - .frame_lengths = {gfxMillisecondsToTicks(200), gfxMillisecondsToTicks(500)}, - .frame_functions = {keyframe_no_operation, keyframe_animate_backlight_color}, + .frame_lengths = {gfxMillisecondsToTicks(0)}, + .frame_functions = {keyframe_set_backlight_color}, }; +bool swap_led_target_color(keyframe_animation_t* animation, visualizer_state_t* state) { + uint32_t temp = next_led_target_color; + next_led_target_color = state->target_lcd_color; + state->target_lcd_color = temp; + return false; +} + +// The color animation animates the LCD color when you change layers +static keyframe_animation_t two_led_colors = { + .num_frames = 2, + .loop = true, + .frame_lengths = {gfxMillisecondsToTicks(1000), gfxMillisecondsToTicks(0)}, + .frame_functions = {keyframe_set_backlight_color, swap_led_target_color}, +}; // The LCD animation alternates between the layer name display and a // bitmap that displays all active layers @@ -177,6 +211,45 @@ void initialize_user_visualizer(visualizer_state_t* state) { start_keyframe_animation(&startup_animation); } +static const uint32_t red; +static const uint32_t green; +static const uint32_t blue; + +inline bool is_led_on(visualizer_user_data_t* user_data, uint8_t num) { + return user_data->led_on & (1u << num); +} + +static uint8_t get_led_index_master(visualizer_user_data_t* user_data) { + for (int i=0; i < 3; i++) { + if (is_led_on(user_data, i)) { + return i + 1; + } + } + return 0; +} + +static uint8_t get_led_index_slave(visualizer_user_data_t* user_data) { + uint8_t master_index = get_led_index_master(user_data); + if (master_index!=0) { + for (int i=master_index; i < 3; i++) { + if (is_led_on(user_data, i)) { + return i + 1; + } + } + } + + return 0; +} + +static uint8_t get_secondary_led_index(visualizer_user_data_t* user_data) { + if (is_led_on(user_data, 0) && + is_led_on(user_data, 1) && + is_led_on(user_data, 2)) { + return 3; + } + return 0; +} + void update_user_visualizer_state(visualizer_state_t* state, visualizer_keyboard_status_t prev_status) { // Check the status here to start and stop animations // You might have to save some state, like the current animation here so that you can start the right @@ -186,9 +259,38 @@ void update_user_visualizer_state(visualizer_state_t* state, visualizer_keyboard // This is also important because the slave won't have access to the active layer for example outside the // status. - if (lcd_state == LCD_STATE_INITIAL) { - state->target_lcd_color = LCD_COLOR(0x40, 0xB0, 0xFF); - start_keyframe_animation(&color_animation); + + visualizer_user_data_t* user_data_new = (visualizer_user_data_t*)state->status.user_data; + visualizer_user_data_t* user_data_old = (visualizer_user_data_t*)prev_status.user_data; + + uint8_t new_index; + uint8_t old_index; + + if (is_serial_link_master()) { + new_index = get_led_index_master(user_data_new); + old_index = get_led_index_master(user_data_old); + } + else { + new_index = get_led_index_slave(user_data_new); + old_index = get_led_index_slave(user_data_old); + } + uint8_t new_secondary_index = get_secondary_led_index(user_data_new); + uint8_t old_secondary_index = get_secondary_led_index(user_data_old); + + if (lcd_state == LCD_STATE_INITIAL || + new_index != old_index || + new_secondary_index != old_secondary_index) { + + if (new_secondary_index != 0) { + state->target_lcd_color = led_emulation_colors[new_index]; + next_led_target_color = led_emulation_colors[new_secondary_index]; + stop_keyframe_animation(&one_led_color); + start_keyframe_animation(&two_led_colors); + } else { + state->target_lcd_color = led_emulation_colors[new_index]; + stop_keyframe_animation(&two_led_colors); + start_keyframe_animation(&one_led_color); + } } if (state->status.leds) { @@ -233,3 +335,56 @@ void user_visualizer_resume(visualizer_state_t* state) { lcd_state = LCD_STATE_INITIAL; start_keyframe_animation(&resume_animation); } + +void ergodox_board_led_on(void){ + // No board led support +} + +void ergodox_right_led_1_on(void){ + user_data_keyboard.led_on |= (1u << 0); + visualizer_set_user_data(&user_data_keyboard); +} + +void ergodox_right_led_2_on(void){ + user_data_keyboard.led_on |= (1u << 1); + visualizer_set_user_data(&user_data_keyboard); +} + +void ergodox_right_led_3_on(void){ + user_data_keyboard.led_on |= (1u << 2); + visualizer_set_user_data(&user_data_keyboard); +} + +void ergodox_board_led_off(void){ + // No board led support +} + +void ergodox_right_led_1_off(void){ + user_data_keyboard.led_on &= ~(1u << 0); + visualizer_set_user_data(&user_data_keyboard); +} + +void ergodox_right_led_2_off(void){ + user_data_keyboard.led_on &= ~(1u << 1); + visualizer_set_user_data(&user_data_keyboard); +} + +void ergodox_right_led_3_off(void){ + user_data_keyboard.led_on &= ~(1u << 2); + visualizer_set_user_data(&user_data_keyboard); +} + +void ergodox_right_led_1_set(uint8_t n) { + user_data_keyboard.led1 = n; + visualizer_set_user_data(&user_data_keyboard); +} + +void ergodox_right_led_2_set(uint8_t n) { + user_data_keyboard.led2 = n; + visualizer_set_user_data(&user_data_keyboard); +} + +void ergodox_right_led_3_set(uint8_t n) { + user_data_keyboard.led3 = n; + visualizer_set_user_data(&user_data_keyboard); +} |