From 14b7602a65dedaf51db1c9288144765d43a83a15 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Tue, 8 May 2018 15:24:18 -0400 Subject: Adds IS31FL3731 RGB Matrix Implementation (#2910) * adds is31fl3731 rgb matrix implementation * fix build script for force pushes * allow bootloader size to be overwritten * adds planck light implementation * split led config into 2 arrays * idk * betterize register handling * update planck implementation * update planck * refine rgb interface * cleanup names, rgb matrix * start documentation * finish up docs * add effects list * clean-up merge * add RGB_MATRIX_SKIP_FRAMES * add support for at90usb1286 to bootloader options --- quantum/color.c | 87 +++++ quantum/color.h | 55 ++++ quantum/quantum.c | 23 +- quantum/quantum.h | 6 + quantum/rgb.h | 47 +++ quantum/rgb_matrix.c | 873 +++++++++++++++++++++++++++++++++++++++++++++++++++ quantum/rgb_matrix.h | 135 ++++++++ 7 files changed, 1224 insertions(+), 2 deletions(-) create mode 100644 quantum/color.c create mode 100644 quantum/color.h create mode 100644 quantum/rgb.h create mode 100644 quantum/rgb_matrix.c create mode 100644 quantum/rgb_matrix.h (limited to 'quantum') diff --git a/quantum/color.c b/quantum/color.c new file mode 100644 index 000000000..8ede053e7 --- /dev/null +++ b/quantum/color.c @@ -0,0 +1,87 @@ +/* Copyright 2017 Jason Williams + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include "color.h" +#include "led_tables.h" +#include "progmem.h" + +RGB hsv_to_rgb( HSV hsv ) +{ + RGB rgb; + uint8_t region, p, q, t; + uint16_t h, s, v, remainder; + + if ( hsv.s == 0 ) + { + rgb.r = hsv.v; + rgb.g = hsv.v; + rgb.b = hsv.v; + return rgb; + } + + h = hsv.h; + s = hsv.s; + v = hsv.v; + + region = h / 43; + remainder = (h - (region * 43)) * 6; + + p = (v * (255 - s)) >> 8; + q = (v * (255 - ((s * remainder) >> 8))) >> 8; + t = (v * (255 - ((s * (255 - remainder)) >> 8))) >> 8; + + switch ( region ) + { + case 0: + rgb.r = v; + rgb.g = t; + rgb.b = p; + break; + case 1: + rgb.r = q; + rgb.g = v; + rgb.b = p; + break; + case 2: + rgb.r = p; + rgb.g = v; + rgb.b = t; + break; + case 3: + rgb.r = p; + rgb.g = q; + rgb.b = v; + break; + case 4: + rgb.r = t; + rgb.g = p; + rgb.b = v; + break; + default: + rgb.r = v; + rgb.g = p; + rgb.b = q; + break; + } + + rgb.r = pgm_read_byte( &CIE1931_CURVE[rgb.r] ); + rgb.g = pgm_read_byte( &CIE1931_CURVE[rgb.g] ); + rgb.b = pgm_read_byte( &CIE1931_CURVE[rgb.b] ); + + return rgb; +} + diff --git a/quantum/color.h b/quantum/color.h new file mode 100644 index 000000000..9d51d45ad --- /dev/null +++ b/quantum/color.h @@ -0,0 +1,55 @@ +/* Copyright 2017 Jason Williams + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#ifndef COLOR_H +#define COLOR_H + +#include +#include + + +#if defined(__GNUC__) +#define PACKED __attribute__ ((__packed__)) +#else +#define PACKED +#endif + +#if defined(_MSC_VER) +#pragma pack( push, 1 ) +#endif + +typedef struct PACKED +{ + uint8_t r; + uint8_t g; + uint8_t b; +} RGB; + +typedef struct PACKED +{ + uint8_t h; + uint8_t s; + uint8_t v; +} HSV; + +#if defined(_MSC_VER) +#pragma pack( pop ) +#endif + +RGB hsv_to_rgb( HSV hsv ); + +#endif // COLOR_H diff --git a/quantum/quantum.c b/quantum/quantum.c index 2662e5ef1..e1bc8b242 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -230,6 +230,9 @@ bool process_record_quantum(keyrecord_t *record) { process_clicky(keycode, record) && #endif //AUDIO_CLICKY process_record_kb(keycode, record) && + #if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_KEYPRESSES) + process_rgb_matrix(keycode, record) && + #endif #if defined(MIDI_ENABLE) && defined(MIDI_ADVANCED) process_midi(keycode, record) && #endif @@ -307,7 +310,7 @@ bool process_record_quantum(keyrecord_t *record) { } return false; #endif - #ifdef RGBLIGHT_ENABLE + #if defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE) case RGB_TOG: if (record->event.pressed) { rgblight_toggle(); @@ -835,9 +838,18 @@ void matrix_init_quantum() { #ifdef AUDIO_ENABLE audio_init(); #endif + #ifdef RGB_MATRIX_ENABLE + rgb_matrix_init_drivers(); + #endif matrix_init_kb(); } +uint8_t rgb_matrix_task_counter = 0; + +#ifndef RGB_MATRIX_SKIP_FRAMES + #define RGB_MATRIX_SKIP_FRAMES 1 +#endif + void matrix_scan_quantum() { #if defined(AUDIO_ENABLE) matrix_scan_music(); @@ -855,9 +867,16 @@ void matrix_scan_quantum() { backlight_task(); #endif + #ifdef RGB_MATRIX_ENABLE + rgb_matrix_task(); + if (rgb_matrix_task_counter == 0) { + rgb_matrix_update_pwm_buffers(); + } + rgb_matrix_task_counter = ((rgb_matrix_task_counter + 1) % (RGB_MATRIX_SKIP_FRAMES + 1)); + #endif + matrix_scan_kb(); } - #if defined(BACKLIGHT_ENABLE) && defined(BACKLIGHT_PIN) static const uint8_t backlight_pin = BACKLIGHT_PIN; diff --git a/quantum/quantum.h b/quantum/quantum.h index 195f578de..2958a0abd 100644 --- a/quantum/quantum.h +++ b/quantum/quantum.h @@ -27,9 +27,15 @@ #ifdef BACKLIGHT_ENABLE #include "backlight.h" #endif +#if !defined(RGBLIGHT_ENABLE) && !defined(RGB_MATRIX_ENABLE) + #include "rgb.h" +#endif #ifdef RGBLIGHT_ENABLE #include "rgblight.h" #endif +#ifdef RGB_MATRIX_ENABLE + #include "rgb_matrix.h" +#endif #include "action_layer.h" #include "eeconfig.h" #include diff --git a/quantum/rgb.h b/quantum/rgb.h new file mode 100644 index 000000000..fbdda293f --- /dev/null +++ b/quantum/rgb.h @@ -0,0 +1,47 @@ +/* Copyright 2017 Jack Humbert + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef RGB_H +#define RGB_H + +__attribute__((weak)) +void rgblight_toggle(void) {}; + +__attribute__((weak)) +void rgblight_step(void) {}; + +__attribute__((weak)) +void rgblight_step_reverse(void) {}; + +__attribute__((weak)) +void rgblight_increase_hue(void) {}; + +__attribute__((weak)) +void rgblight_decrease_hue(void) {}; + +__attribute__((weak)) +void rgblight_increase_sat(void) {}; + +__attribute__((weak)) +void rgblight_decrease_sat(void) {}; + +__attribute__((weak)) +void rgblight_increase_val(void) {}; + +__attribute__((weak)) +void rgblight_decrease_val(void) {}; + +#endif \ No newline at end of file diff --git a/quantum/rgb_matrix.c b/quantum/rgb_matrix.c new file mode 100644 index 000000000..6cb0478f7 --- /dev/null +++ b/quantum/rgb_matrix.c @@ -0,0 +1,873 @@ +/* Copyright 2017 Jason Williams + * Copyright 2017 Jack Humbert + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include "rgb_matrix.h" +#include +#include "TWIlib.h" +#include +#include +#include "progmem.h" +#include "config.h" +#include "eeprom.h" +#include "lufa.h" +#include + +rgb_config_t rgb_matrix_config; + +#ifndef RGB_DISABLE_AFTER_TIMEOUT + #define RGB_DISABLE_AFTER_TIMEOUT 0 +#endif + +#ifndef RGB_DISABLE_WHEN_USB_SUSPENDED + #define RGB_DISABLE_WHEN_USB_SUSPENDED false +#endif + +#ifndef EECONFIG_RGB_MATRIX + #define EECONFIG_RGB_MATRIX EECONFIG_RGBLIGHT +#endif + +bool g_suspend_state = false; + +// Global tick at 20 Hz +uint32_t g_tick = 0; + +// Ticks since this key was last hit. +uint8_t g_key_hit[DRIVER_LED_TOTAL]; + +// Ticks since any key was last hit. +uint32_t g_any_key_hit = 0; + +#ifndef PI +#define PI 3.14159265 +#endif + +uint32_t eeconfig_read_rgb_matrix(void) { + return eeprom_read_dword(EECONFIG_RGB_MATRIX); +} +void eeconfig_update_rgb_matrix(uint32_t val) { + eeprom_update_dword(EECONFIG_RGB_MATRIX, val); +} +void eeconfig_update_rgb_matrix_default(void) { + dprintf("eeconfig_update_rgb_matrix_default\n"); + rgb_matrix_config.enable = 1; + rgb_matrix_config.mode = RGB_MATRIX_CYCLE_LEFT_RIGHT; + rgb_matrix_config.hue = 0; + rgb_matrix_config.sat = 255; + rgb_matrix_config.val = 255; + eeconfig_update_rgb_matrix(rgb_matrix_config.raw); +} +void eeconfig_debug_rgb_matrix(void) { + dprintf("rgb_matrix_config eprom\n"); + dprintf("rgb_matrix_config.enable = %d\n", rgb_matrix_config.enable); + dprintf("rgb_matrix_config.mode = %d\n", rgb_matrix_config.mode); + dprintf("rgb_matrix_config.hue = %d\n", rgb_matrix_config.hue); + dprintf("rgb_matrix_config.sat = %d\n", rgb_matrix_config.sat); + dprintf("rgb_matrix_config.val = %d\n", rgb_matrix_config.val); +} + +// Last led hit +#define LED_HITS_TO_REMEMBER 8 +uint8_t g_last_led_hit[LED_HITS_TO_REMEMBER] = {255}; +uint8_t g_last_led_count = 0; + +void map_row_column_to_led( uint8_t row, uint8_t column, uint8_t *led_i, uint8_t *led_count) { + rgb_led led; + *led_count = 0; + + for (uint8_t i = 0; i < DRIVER_LED_TOTAL; i++) { + // map_index_to_led(i, &led); + led = g_rgb_leds[i]; + if (row == led.matrix_co.row && column == led.matrix_co.col) { + led_i[*led_count] = i; + (*led_count)++; + } + } +} + + +void rgb_matrix_update_pwm_buffers(void) { + IS31FL3731_update_pwm_buffers( DRIVER_ADDR_1, DRIVER_ADDR_2 ); + IS31FL3731_update_led_control_registers( DRIVER_ADDR_1, DRIVER_ADDR_2 ); +} + +void rgb_matrix_set_color( int index, uint8_t red, uint8_t green, uint8_t blue ) { + IS31FL3731_set_color( index, red, green, blue ); +} + +void rgb_matrix_set_color_all( uint8_t red, uint8_t green, uint8_t blue ) { + IS31FL3731_set_color_all( red, green, blue ); +} + + +bool process_rgb_matrix(uint16_t keycode, keyrecord_t *record) { + if ( record->event.pressed ) { + uint8_t led[8], led_count; + map_row_column_to_led(record->event.key.row, record->event.key.col, led, &led_count); + if (led_count > 0) { + for (uint8_t i = LED_HITS_TO_REMEMBER; i > 1; i--) { + g_last_led_hit[i - 1] = g_last_led_hit[i - 2]; + } + g_last_led_hit[0] = led[0]; + g_last_led_count = MIN(LED_HITS_TO_REMEMBER, g_last_led_count + 1); + } + for(uint8_t i = 0; i < led_count; i++) + g_key_hit[led[i]] = 0; + g_any_key_hit = 0; + } else { + #ifdef RGB_MATRIX_KEYRELEASES + uint8_t led[8], led_count; + map_row_column_to_led(record->event.key.row, record->event.key.col, led, &led_count); + for(uint8_t i = 0; i < led_count; i++) + g_key_hit[led[i]] = 255; + + g_any_key_hit = 255; + #endif + } + return true; +} + +void rgb_matrix_set_suspend_state(bool state) { + g_suspend_state = state; +} + +void rgb_matrix_test(void) { + // Mask out bits 4 and 5 + // This 2-bit value will stay the same for 16 ticks. + switch ( (g_tick & 0x30) >> 4 ) + { + case 0: + { + rgb_matrix_set_color_all( 20, 0, 0 ); + break; + } + case 1: + { + rgb_matrix_set_color_all( 0, 20, 0 ); + break; + } + case 2: + { + rgb_matrix_set_color_all( 0, 0, 20 ); + break; + } + case 3: + { + rgb_matrix_set_color_all( 20, 20, 20 ); + break; + } + } +} + +// This tests the LEDs +// Note that it will change the LED control registers +// in the LED drivers, and leave them in an invalid +// state for other backlight effects. +// ONLY USE THIS FOR TESTING LEDS! +void rgb_matrix_single_LED_test(void) { + static uint8_t color = 0; // 0,1,2 for R,G,B + static uint8_t row = 0; + static uint8_t column = 0; + + static uint8_t tick = 0; + tick++; + + if ( tick > 2 ) + { + tick = 0; + column++; + } + if ( column > MATRIX_COLS ) + { + column = 0; + row++; + } + if ( row > MATRIX_ROWS ) + { + row = 0; + color++; + } + if ( color > 2 ) + { + color = 0; + } + + uint8_t led[8], led_count; + map_row_column_to_led(row,column,led,&led_count); + for(uint8_t i = 0; i < led_count; i++) { + rgb_matrix_set_color_all( 40, 40, 40 ); + rgb_matrix_test_led( led[i], color==0, color==1, color==2 ); + } +} + +// All LEDs off +void rgb_matrix_all_off(void) { + rgb_matrix_set_color_all( 0, 0, 0 ); +} + +// Solid color +void rgb_matrix_solid_color(void) { + HSV hsv = { .h = rgb_matrix_config.hue, .s = rgb_matrix_config.sat, .v = rgb_matrix_config.val }; + RGB rgb = hsv_to_rgb( hsv ); + rgb_matrix_set_color_all( rgb.r, rgb.g, rgb.b ); +} + +void rgb_matrix_solid_reactive(void) { + // Relies on hue being 8-bit and wrapping + for ( int i=0; i 127 ) + { + deltaH -= 256; + } + else if ( deltaH < -127 ) + { + deltaH += 256; + } + // Divide delta by 4, this gives the delta per row + deltaH /= 4; + + int16_t s1 = rgb_matrix_config.sat; + int16_t s2 = rgb_matrix_config.hue; + int16_t deltaS = ( s2 - s1 ) / 4; + + HSV hsv = { .h = 0, .s = 255, .v = rgb_matrix_config.val }; + RGB rgb; + Point point; + for ( int i=0; i>4); + // Relies on hue being 8-bit and wrapping + hsv.h = rgb_matrix_config.hue + ( deltaH * y ); + hsv.s = rgb_matrix_config.sat + ( deltaS * y ); + rgb = hsv_to_rgb( hsv ); + rgb_matrix_set_color( i, rgb.r, rgb.g, rgb.b ); + } +} + +void rgb_matrix_raindrops(bool initialize) { + int16_t h1 = rgb_matrix_config.hue; + int16_t h2 = (rgb_matrix_config.hue + 180) % 360; + int16_t deltaH = h2 - h1; + deltaH /= 4; + + // Take the shortest path between hues + if ( deltaH > 127 ) + { + deltaH -= 256; + } + else if ( deltaH < -127 ) + { + deltaH += 256; + } + + int16_t s1 = rgb_matrix_config.sat; + int16_t s2 = rgb_matrix_config.sat; + int16_t deltaS = ( s2 - s1 ) / 4; + + HSV hsv; + RGB rgb; + + // Change one LED every tick + uint8_t led_to_change = ( g_tick & 0x000 ) == 0 ? rand() % DRIVER_LED_TOTAL : 255; + + for ( int i=0; i 0 && g_any_key_hit > RGB_DISABLE_AFTER_TIMEOUT * 60 * 20)); + uint8_t effect = suspend_backlight ? 0 : rgb_matrix_config.mode; + + // Keep track of the effect used last time, + // detect change in effect, so each effect can + // have an optional initialization. + static uint8_t effect_last = 255; + bool initialize = effect != effect_last; + effect_last = effect; + + // this gets ticked at 20 Hz. + // each effect can opt to do calculations + // and/or request PWM buffer updates. + switch ( effect ) { + case RGB_MATRIX_SOLID_COLOR: + rgb_matrix_solid_color(); + break; + case RGB_MATRIX_SOLID_REACTIVE: + rgb_matrix_solid_reactive(); + break; + case RGB_MATRIX_ALPHAS_MODS: + rgb_matrix_alphas_mods(); + break; + case RGB_MATRIX_DUAL_BEACON: + rgb_matrix_dual_beacon(); + break; + case RGB_MATRIX_GRADIENT_UP_DOWN: + rgb_matrix_gradient_up_down(); + break; + case RGB_MATRIX_RAINDROPS: + rgb_matrix_raindrops( initialize ); + break; + case RGB_MATRIX_CYCLE_ALL: + rgb_matrix_cycle_all(); + break; + case RGB_MATRIX_CYCLE_LEFT_RIGHT: + rgb_matrix_cycle_left_right(); + break; + case RGB_MATRIX_CYCLE_UP_DOWN: + rgb_matrix_cycle_up_down(); + break; + case RGB_MATRIX_RAINBOW_BEACON: + rgb_matrix_rainbow_beacon(); + break; + case RGB_MATRIX_RAINBOW_PINWHEELS: + rgb_matrix_rainbow_pinwheels(); + break; + case RGB_MATRIX_RAINBOW_MOVING_CHEVRON: + rgb_matrix_rainbow_moving_chevron(); + break; + case RGB_MATRIX_JELLYBEAN_RAINDROPS: + rgb_matrix_jellybean_raindrops( initialize ); + break; + #ifdef RGB_MATRIX_KEYPRESSES + case RGB_MATRIX_SPLASH: + rgb_matrix_splash(); + break; + case RGB_MATRIX_MULTISPLASH: + rgb_matrix_multisplash(); + break; + case RGB_MATRIX_SOLID_SPLASH: + rgb_matrix_solid_splash(); + break; + case RGB_MATRIX_SOLID_MULTISPLASH: + rgb_matrix_solid_multisplash(); + break; + #endif + default: + rgb_matrix_custom(); + break; + } + + if ( ! suspend_backlight ) { + rgb_matrix_indicators(); + } + +} + +void rgb_matrix_indicators(void) { + rgb_matrix_indicators_kb(); + rgb_matrix_indicators_user(); +} + +__attribute__((weak)) +void rgb_matrix_indicators_kb(void) {} + +__attribute__((weak)) +void rgb_matrix_indicators_user(void) {} + + +// void rgb_matrix_set_indicator_index( uint8_t *index, uint8_t row, uint8_t column ) +// { +// if ( row >= MATRIX_ROWS ) +// { +// // Special value, 255=none, 254=all +// *index = row; +// } +// else +// { +// // This needs updated to something like +// // uint8_t led[8], led_count; +// // map_row_column_to_led(row,column,led,&led_count); +// // for(uint8_t i = 0; i < led_count; i++) +// map_row_column_to_led( row, column, index ); +// } +// } + +void rgb_matrix_init_drivers(void) { + //sei(); + + // Initialize TWI + TWIInit(); + IS31FL3731_init( DRIVER_ADDR_1 ); + IS31FL3731_init( DRIVER_ADDR_2 ); + + for ( int index = 0; index < DRIVER_LED_TOTAL; index++ ) { + bool enabled = true; + // This only caches it for later + IS31FL3731_set_led_control_register( index, enabled, enabled, enabled ); + } + // This actually updates the LED drivers + IS31FL3731_update_led_control_registers( DRIVER_ADDR_1, DRIVER_ADDR_2 ); + + // TODO: put the 1 second startup delay here? + + // clear the key hits + for ( int led=0; ledh = eeprom_read_byte(address); +// hsv->s = eeprom_read_byte(address+1); +// hsv->v = eeprom_read_byte(address+2); +// } + +// void backlight_set_key_color( uint8_t row, uint8_t column, HSV hsv ) +// { +// uint8_t led[8], led_count; +// map_row_column_to_led(row,column,led,&led_count); +// for(uint8_t i = 0; i < led_count; i++) { +// if ( led[i] < DRIVER_LED_TOTAL ) +// { +// void *address = backlight_get_custom_key_color_eeprom_address(led[i]); +// eeprom_update_byte(address, hsv.h); +// eeprom_update_byte(address+1, hsv.s); +// eeprom_update_byte(address+2, hsv.v); +// } +// } +// } + +void rgb_matrix_test_led( uint8_t index, bool red, bool green, bool blue ) { + for ( int i=0; i= RGB_MATRIX_EFFECT_MAX) + rgb_matrix_config.mode = 1; + eeconfig_update_rgb_matrix(rgb_matrix_config.raw); +} + +void rgblight_step_reverse(void) { + rgb_matrix_config.mode--; + if (rgb_matrix_config.mode <= 1) + rgb_matrix_config.mode = (RGB_MATRIX_EFFECT_MAX - 1); + eeconfig_update_rgb_matrix(rgb_matrix_config.raw); +} + +void rgblight_increase_hue(void) { + rgb_matrix_config.hue = increment( rgb_matrix_config.hue, 8, 0, 255 ); + eeconfig_update_rgb_matrix(rgb_matrix_config.raw); +} + +void rgblight_decrease_hue(void) { + rgb_matrix_config.hue = decrement( rgb_matrix_config.hue, 8, 0, 255 ); + eeconfig_update_rgb_matrix(rgb_matrix_config.raw); +} + +void rgblight_increase_sat(void) { + rgb_matrix_config.sat = increment( rgb_matrix_config.sat, 8, 0, 255 ); + eeconfig_update_rgb_matrix(rgb_matrix_config.raw); +} + +void rgblight_decrease_sat(void) { + rgb_matrix_config.sat = decrement( rgb_matrix_config.sat, 8, 0, 255 ); + eeconfig_update_rgb_matrix(rgb_matrix_config.raw); +} + +void rgblight_increase_val(void) { + rgb_matrix_config.val = increment( rgb_matrix_config.val, 8, 0, 255 ); + eeconfig_update_rgb_matrix(rgb_matrix_config.raw); +} + +void rgblight_decrease_val(void) { + rgb_matrix_config.val = decrement( rgb_matrix_config.val, 8, 0, 255 ); + eeconfig_update_rgb_matrix(rgb_matrix_config.raw); +} + +void rgblight_mode(uint8_t mode) { + rgb_matrix_config.mode = mode; + eeconfig_update_rgb_matrix(rgb_matrix_config.raw); +} + +uint32_t rgblight_get_mode(void) { + return rgb_matrix_config.mode; +} diff --git a/quantum/rgb_matrix.h b/quantum/rgb_matrix.h new file mode 100644 index 000000000..ef93c6d5c --- /dev/null +++ b/quantum/rgb_matrix.h @@ -0,0 +1,135 @@ +/* Copyright 2017 Jason Williams + * Copyright 2017 Jack Humbert + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef RGB_MATRIX_H +#define RGB_MATRIX_H + +#include +#include +#include "color.h" +#include "is31fl3731.h" +#include "quantum.h" + +typedef struct Point { + uint8_t x; + uint8_t y; +} __attribute__((packed)) Point; + +typedef struct rgb_led { + union { + uint8_t raw; + struct { + uint8_t row:4; // 16 max + uint8_t col:4; // 16 max + }; + } matrix_co; + Point point; + uint8_t modifier:1; +} __attribute__((packed)) rgb_led; + + +extern const rgb_led g_rgb_leds[DRIVER_LED_TOTAL]; + +typedef struct +{ + HSV color; + uint8_t index; +} rgb_indicator; + +typedef union { + uint32_t raw; + struct { + bool enable :1; + uint8_t mode :6; + uint16_t hue :9; + uint8_t sat :8; + uint8_t val :8; + }; +} rgb_config_t; + +enum rgb_matrix_effects { + RGB_MATRIX_SOLID_COLOR = 1, + RGB_MATRIX_SOLID_REACTIVE, + RGB_MATRIX_ALPHAS_MODS, + RGB_MATRIX_DUAL_BEACON, + RGB_MATRIX_GRADIENT_UP_DOWN, + RGB_MATRIX_RAINDROPS, + RGB_MATRIX_CYCLE_ALL, + RGB_MATRIX_CYCLE_LEFT_RIGHT, + RGB_MATRIX_CYCLE_UP_DOWN, + RGB_MATRIX_RAINBOW_BEACON, + RGB_MATRIX_RAINBOW_PINWHEELS, + RGB_MATRIX_RAINBOW_MOVING_CHEVRON, + RGB_MATRIX_JELLYBEAN_RAINDROPS, +#ifdef RGB_MATRIX_KEYPRESSES + RGB_MATRIX_SPLASH, + RGB_MATRIX_MULTISPLASH, + RGB_MATRIX_SOLID_SPLASH, + RGB_MATRIX_SOLID_MULTISPLASH, +#endif + RGB_MATRIX_EFFECT_MAX +}; + +void rgb_matrix_set_color( int index, uint8_t red, uint8_t green, uint8_t blue ); + +// This runs after another backlight effect and replaces +// colors already set +void rgb_matrix_indicators(void); +void rgb_matrix_indicators_kb(void); +void rgb_matrix_indicators_user(void); + +void rgb_matrix_single_LED_test(void); + +void rgb_matrix_init_drivers(void); + +void rgb_matrix_set_suspend_state(bool state); +void rgb_matrix_set_indicator_state(uint8_t state); + + +void rgb_matrix_task(void); + +// This should not be called from an interrupt +// (eg. from a timer interrupt). +// Call this while idle (in between matrix scans). +// If the buffer is dirty, it will update the driver with the buffer. +void rgb_matrix_update_pwm_buffers(void); + +bool process_rgb_matrix(uint16_t keycode, keyrecord_t *record); + +void rgb_matrix_increase(void); +void rgb_matrix_decrease(void); + +// void *backlight_get_key_color_eeprom_address(uint8_t led); +// void backlight_get_key_color( uint8_t led, HSV *hsv ); +// void backlight_set_key_color( uint8_t row, uint8_t column, HSV hsv ); + +void rgb_matrix_test_led( uint8_t index, bool red, bool green, bool blue ); +uint32_t rgb_matrix_get_tick(void); + +void rgblight_toggle(void); +void rgblight_step(void); +void rgblight_step_reverse(void); +void rgblight_increase_hue(void); +void rgblight_decrease_hue(void); +void rgblight_increase_sat(void); +void rgblight_decrease_sat(void); +void rgblight_increase_val(void); +void rgblight_decrease_val(void); +void rgblight_mode(uint8_t mode); +uint32_t rgblight_get_mode(void); + +#endif -- cgit v1.2.3-24-g4f1b