diff options
author | James Young <18669334+noroadsleft@users.noreply.github.com> | 2020-11-28 12:02:18 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-11-28 12:02:18 -0800 |
commit | c66df1664497546f32662409778731143e45a552 (patch) | |
tree | da73a2d532a27685a31d932b3a44a707d4a3af81 /tmk_core/protocol/arm_atsam/led_matrix.c | |
parent | 15385d4113414d42bd062c60c9de5df797d3157f (diff) |
2020 November 28 Breaking Changes Update (#11053)
* Branch point for 2020 November 28 Breaking Change
* Remove matrix_col_t to allow MATRIX_ROWS > 32 (#10183)
* Add support for soft serial to ATmega32U2 (#10204)
* Change MIDI velocity implementation to allow direct control of velocity value (#9940)
* Add ability to build a subset of all keyboards based on platform.
* Actually use eeprom_driver_init().
* Make bootloader_jump weak for ChibiOS. (#10417)
* Joystick 16-bit support (#10439)
* Per-encoder resolutions (#10259)
* Share button state from mousekey to pointing_device (#10179)
* Add hotfix for chibios keyboards not wake (#10088)
* Add advanced/efficient RGB Matrix Indicators (#8564)
* Naming change.
* Support for STM32 GPIOF,G,H,I,J,K (#10206)
* Add milc as a dependency and remove the installed milc (#10563)
* ChibiOS upgrade: early init conversions (#10214)
* ChibiOS upgrade: configuration file migrator (#9952)
* Haptic and solenoid cleanup (#9700)
* XD75 cleanup (#10524)
* OLED display update interval support (#10388)
* Add definition based on currently-selected serial driver. (#10716)
* New feature: Retro Tapping per key (#10622)
* Allow for modification of output RGB values when using rgblight/rgb_matrix. (#10638)
* Add housekeeping task callbacks so that keyboards/keymaps are capable of executing code for each main loop iteration. (#10530)
* Rescale both ChibiOS and AVR backlighting.
* Reduce Helix keyboard build variation (#8669)
* Minor change to behavior allowing display updates to continue between task ticks (#10750)
* Some GPIO manipulations in matrix.c change to atomic. (#10491)
* qmk cformat (#10767)
* [Keyboard] Update the Speedo firmware for v3.0 (#10657)
* Maartenwut/Maarten namechange to evyd13/Evy (#10274)
* [quantum] combine repeated lines of code (#10837)
* Add step sequencer feature (#9703)
* aeboards/ext65 refactor (#10820)
* Refactor xelus/dawn60 for Rev2 later (#10584)
* add DEBUG_MATRIX_SCAN_RATE_ENABLE to common_features.mk (#10824)
* [Core] Added `add_oneshot_mods` & `del_oneshot_mods` (#10549)
* update chibios os usb for the otg driver (#8893)
* Remove HD44780 References, Part 4 (#10735)
* [Keyboard] Add Valor FRL TKL (+refactor) (#10512)
* Fix cursor position bug in oled_write_raw functions (#10800)
* Fixup version.h writing when using SKIP_VERSION=yes (#10972)
* Allow for certain code in the codebase assuming length of string. (#10974)
* Add AT90USB support for serial.c (#10706)
* Auto shift: support repeats and early registration (#9826)
* Rename ledmatrix.h to match .c file (#7949)
* Split RGB_MATRIX_ENABLE into _ENABLE and _DRIVER (#10231)
* Split LED_MATRIX_ENABLE into _ENABLE and _DRIVER (#10840)
* Merge point for 2020 Nov 28 Breaking Change
Diffstat (limited to 'tmk_core/protocol/arm_atsam/led_matrix.c')
-rw-r--r-- | tmk_core/protocol/arm_atsam/led_matrix.c | 472 |
1 files changed, 0 insertions, 472 deletions
diff --git a/tmk_core/protocol/arm_atsam/led_matrix.c b/tmk_core/protocol/arm_atsam/led_matrix.c deleted file mode 100644 index 69cb03a9f7..0000000000 --- a/tmk_core/protocol/arm_atsam/led_matrix.c +++ /dev/null @@ -1,472 +0,0 @@ -/* -Copyright 2018 Massdrop Inc. - -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 <http://www.gnu.org/licenses/>. -*/ - -#include "arm_atsam_protocol.h" -#include "tmk_core/common/led.h" -#include "rgb_matrix.h" -#include <string.h> -#include <math.h> - -#ifdef USE_MASSDROP_CONFIGURATOR -__attribute__((weak)) led_instruction_t led_instructions[] = {{.end = 1}}; -static void led_matrix_massdrop_config_override(int i); -#endif // USE_MASSDROP_CONFIGURATOR - -void SERCOM1_0_Handler(void) { - if (SERCOM1->I2CM.INTFLAG.bit.ERROR) { - SERCOM1->I2CM.INTFLAG.reg = SERCOM_I2CM_INTENCLR_ERROR; - } -} - -void DMAC_0_Handler(void) { - if (DMAC->Channel[0].CHINTFLAG.bit.TCMPL) { - DMAC->Channel[0].CHINTFLAG.reg = DMAC_CHINTENCLR_TCMPL; - - i2c1_stop(); - - i2c_led_q_running = 0; - - i2c_led_q_run(); - - return; - } - - if (DMAC->Channel[0].CHINTFLAG.bit.TERR) { - DMAC->Channel[0].CHINTFLAG.reg = DMAC_CHINTENCLR_TERR; - } -} - -issi3733_driver_t issidrv[ISSI3733_DRIVER_COUNT]; - -issi3733_led_t led_map[ISSI3733_LED_COUNT] = ISSI3733_LED_MAP; -RGB led_buffer[ISSI3733_LED_COUNT]; - -uint8_t gcr_desired; -uint8_t gcr_actual; -uint8_t gcr_actual_last; -#ifdef USE_MASSDROP_CONFIGURATOR -uint8_t gcr_breathe; -float breathe_mult; -float pomod; -#endif - -#define ACT_GCR_NONE 0 -#define ACT_GCR_INC 1 -#define ACT_GCR_DEC 2 - -#define LED_GCR_STEP_AUTO 2 - -static uint8_t gcr_min_counter; -static uint8_t v_5v_cat_hit; - -// WARNING: Automatic GCR is in place to prevent USB shutdown and LED driver overloading -void gcr_compute(void) { - uint8_t action = ACT_GCR_NONE; - uint8_t gcr_use = gcr_desired; - -#ifdef USE_MASSDROP_CONFIGURATOR - if (led_animation_breathing) { - gcr_use = gcr_breathe; - } -#endif - - // If the 5v takes a catastrophic hit, disable the LED drivers briefly, assert auto gcr mode, min gcr and let the auto take over - if (v_5v < V5_CAT) { - I2C3733_Control_Set(0); - // CDC_print("USB: WARNING: 5V catastrophic level reached! Disabling LED drivers!\r\n"); //Blocking print is bad here! - v_5v_cat_hit = 20; //~100ms recover - gcr_actual = 0; // Minimize GCR - usb_gcr_auto = 1; // Force auto mode enabled - return; - } else if (v_5v_cat_hit > 1) { - v_5v_cat_hit--; - return; - } else if (v_5v_cat_hit == 1) { - I2C3733_Control_Set(1); - CDC_print("USB: WARNING: Re-enabling LED drivers\r\n"); - v_5v_cat_hit = 0; - return; - } - - if (usb_gcr_auto) { - if (v_5v_avg < V5_LOW) - action = ACT_GCR_DEC; - else if (v_5v_avg > V5_HIGH && gcr_actual < gcr_use) - action = ACT_GCR_INC; - else if (gcr_actual > gcr_use) - action = ACT_GCR_DEC; - } else { - if (gcr_actual < gcr_use) - action = ACT_GCR_INC; - else if (gcr_actual > gcr_use) - action = ACT_GCR_DEC; - } - - if (action == ACT_GCR_NONE) { - gcr_min_counter = 0; - } else if (action == ACT_GCR_INC) { - if (LED_GCR_STEP_AUTO > LED_GCR_MAX - gcr_actual) - gcr_actual = LED_GCR_MAX; // Obey max and prevent wrapping - else - gcr_actual += LED_GCR_STEP_AUTO; - gcr_min_counter = 0; - } else if (action == ACT_GCR_DEC) { - if (LED_GCR_STEP_AUTO > gcr_actual) // Prevent wrapping - { - gcr_actual = 0; - // At this point, power can no longer be cut from the LED drivers, so focus on cutting out extra port if active - if (usb_extra_state != USB_EXTRA_STATE_DISABLED_UNTIL_REPLUG) // If not in a wait for replug state - { - if (usb_extra_state == USB_EXTRA_STATE_ENABLED) // If extra usb is enabled - { - gcr_min_counter++; - if (gcr_min_counter > 200) // 5ms per check = 1s delay - { - USB_ExtraSetState(USB_EXTRA_STATE_DISABLED_UNTIL_REPLUG); - usb_extra_manual = 0; // Force disable manual mode of extra port - if (usb_extra_manual) - CDC_print("USB: Disabling extra port until replug and manual mode toggle!\r\n"); - else - CDC_print("USB: Disabling extra port until replug!\r\n"); - } - } - } - } else { - // Power successfully cut back from LED drivers - gcr_actual -= LED_GCR_STEP_AUTO; - gcr_min_counter = 0; - -#ifdef USE_MASSDROP_CONFIGURATOR - // If breathe mode is active, the top end can fluctuate if the host can not supply enough current - // So set the breathe GCR to where it becomes stable - if (led_animation_breathing == 1) { - gcr_breathe = gcr_actual; - // PS: At this point, setting breathing to exhale makes a noticebly shorter cycle - // and the same would happen maybe one or two more times. Therefore I'm favoring - // powering through one full breathe and letting gcr settle completely - } -#endif - } - } -} - -void issi3733_prepare_arrays(void) { - memset(issidrv, 0, sizeof(issi3733_driver_t) * ISSI3733_DRIVER_COUNT); - - int i; - uint8_t addrs[ISSI3733_DRIVER_COUNT] = ISSI3773_DRIVER_ADDRESSES; - - for (i = 0; i < ISSI3733_DRIVER_COUNT; i++) { - issidrv[i].addr = addrs[i]; - } - - for (uint8_t i = 0; i < ISSI3733_LED_COUNT; i++) { - // BYTE: 1 + (SW-1)*16 + (CS-1) - led_map[i].rgb.g = issidrv[led_map[i].adr.drv - 1].pwm + 1 + ((led_map[i].adr.swg - 1) * 16 + (led_map[i].adr.cs - 1)); - led_map[i].rgb.r = issidrv[led_map[i].adr.drv - 1].pwm + 1 + ((led_map[i].adr.swr - 1) * 16 + (led_map[i].adr.cs - 1)); - led_map[i].rgb.b = issidrv[led_map[i].adr.drv - 1].pwm + 1 + ((led_map[i].adr.swb - 1) * 16 + (led_map[i].adr.cs - 1)); - - // BYTE: 1 + (SW-1)*2 + (CS-1)/8 - // BIT: (CS-1)%8 - *(issidrv[led_map[i].adr.drv - 1].onoff + 1 + (led_map[i].adr.swg - 1) * 2 + (led_map[i].adr.cs - 1) / 8) |= (1 << ((led_map[i].adr.cs - 1) % 8)); - *(issidrv[led_map[i].adr.drv - 1].onoff + 1 + (led_map[i].adr.swr - 1) * 2 + (led_map[i].adr.cs - 1) / 8) |= (1 << ((led_map[i].adr.cs - 1) % 8)); - *(issidrv[led_map[i].adr.drv - 1].onoff + 1 + (led_map[i].adr.swb - 1) * 2 + (led_map[i].adr.cs - 1) / 8) |= (1 << ((led_map[i].adr.cs - 1) % 8)); - } -} - -void led_matrix_prepare(void) { - for (uint8_t i = 0; i < ISSI3733_LED_COUNT; i++) { - *led_map[i].rgb.r = 0; - *led_map[i].rgb.g = 0; - *led_map[i].rgb.b = 0; - } -} - -void led_set_one(int i, uint8_t r, uint8_t g, uint8_t b) { - if (i < ISSI3733_LED_COUNT) { -#ifdef USE_MASSDROP_CONFIGURATOR - led_matrix_massdrop_config_override(i); -#else - led_buffer[i].r = r; - led_buffer[i].g = g; - led_buffer[i].b = b; -#endif - } -} - -void led_set_all(uint8_t r, uint8_t g, uint8_t b) { - for (uint8_t i = 0; i < ISSI3733_LED_COUNT; i++) { - led_set_one(i, r, g, b); - } -} - -void init(void) { - DBGC(DC_LED_MATRIX_INIT_BEGIN); - - issi3733_prepare_arrays(); - - led_matrix_prepare(); - - gcr_min_counter = 0; - v_5v_cat_hit = 0; - - DBGC(DC_LED_MATRIX_INIT_COMPLETE); -} - -void flush(void) { -#ifdef USE_MASSDROP_CONFIGURATOR - if (!led_enabled) { - return; - } // Prevent calculations and I2C traffic if LED drivers are not enabled -#else - if (!sr_exp_data.bit.SDB_N) { - return; - } // Prevent calculations and I2C traffic if LED drivers are not enabled -#endif - - // Wait for previous transfer to complete - while (i2c_led_q_running) { - } - - // Copy buffer to live DMA region - for (uint8_t i = 0; i < ISSI3733_LED_COUNT; i++) { - *led_map[i].rgb.r = led_buffer[i].r; - *led_map[i].rgb.g = led_buffer[i].g; - *led_map[i].rgb.b = led_buffer[i].b; - } - -#ifdef USE_MASSDROP_CONFIGURATOR - breathe_mult = 1; - - if (led_animation_breathing) { - //+60us 119 LED - led_animation_breathe_cur += BREATHE_STEP * breathe_dir; - - if (led_animation_breathe_cur >= BREATHE_MAX_STEP) - breathe_dir = -1; - else if (led_animation_breathe_cur <= BREATHE_MIN_STEP) - breathe_dir = 1; - - // Brightness curve created for 256 steps, 0 - ~98% - breathe_mult = 0.000015 * led_animation_breathe_cur * led_animation_breathe_cur; - if (breathe_mult > 1) - breathe_mult = 1; - else if (breathe_mult < 0) - breathe_mult = 0; - } - - // This should only be performed once per frame - pomod = (float)((g_rgb_timer / 10) % (uint32_t)(1000.0f / led_animation_speed)) / 10.0f * led_animation_speed; - pomod *= 100.0f; - pomod = (uint32_t)pomod % 10000; - pomod /= 100.0f; - -#endif // USE_MASSDROP_CONFIGURATOR - - uint8_t drvid; - - // NOTE: GCR does not need to be timed with LED processing, but there is really no harm - if (gcr_actual != gcr_actual_last) { - for (drvid = 0; drvid < ISSI3733_DRIVER_COUNT; drvid++) I2C_LED_Q_GCR(drvid); // Queue data - gcr_actual_last = gcr_actual; - } - - for (drvid = 0; drvid < ISSI3733_DRIVER_COUNT; drvid++) I2C_LED_Q_PWM(drvid); // Queue data - - i2c_led_q_run(); -} - -void led_matrix_indicators(void) { - uint8_t kbled = keyboard_leds(); - if (kbled && rgb_matrix_config.enable) { - for (uint8_t i = 0; i < ISSI3733_LED_COUNT; i++) { - if ( -#if USB_LED_NUM_LOCK_SCANCODE != 255 - (led_map[i].scan == USB_LED_NUM_LOCK_SCANCODE && (kbled & (1 << USB_LED_NUM_LOCK))) || -#endif // NUM LOCK -#if USB_LED_CAPS_LOCK_SCANCODE != 255 - (led_map[i].scan == USB_LED_CAPS_LOCK_SCANCODE && (kbled & (1 << USB_LED_CAPS_LOCK))) || -#endif // CAPS LOCK -#if USB_LED_SCROLL_LOCK_SCANCODE != 255 - (led_map[i].scan == USB_LED_SCROLL_LOCK_SCANCODE && (kbled & (1 << USB_LED_SCROLL_LOCK))) || -#endif // SCROLL LOCK -#if USB_LED_COMPOSE_SCANCODE != 255 - (led_map[i].scan == USB_LED_COMPOSE_SCANCODE && (kbled & (1 << USB_LED_COMPOSE))) || -#endif // COMPOSE -#if USB_LED_KANA_SCANCODE != 255 - (led_map[i].scan == USB_LED_KANA_SCANCODE && (kbled & (1 << USB_LED_KANA))) || -#endif // KANA - (0)) { - if (rgb_matrix_get_flags() & LED_FLAG_INDICATOR) { - led_buffer[i].r = 255 - led_buffer[i].r; - led_buffer[i].g = 255 - led_buffer[i].g; - led_buffer[i].b = 255 - led_buffer[i].b; - } - } - } - } -} - -const rgb_matrix_driver_t rgb_matrix_driver = {.init = init, .flush = flush, .set_color = led_set_one, .set_color_all = led_set_all}; - -/*============================================================================== -= Legacy Lighting Support = -==============================================================================*/ - -#ifdef USE_MASSDROP_CONFIGURATOR -// Ported from Massdrop QMK GitHub Repo - -// TODO?: wire these up to keymap.c -uint8_t led_animation_orientation = 0; -uint8_t led_animation_direction = 0; -uint8_t led_animation_breathing = 0; -uint8_t led_animation_id = 0; -float led_animation_speed = 4.0f; -uint8_t led_lighting_mode = LED_MODE_NORMAL; -uint8_t led_enabled = 1; -uint8_t led_animation_breathe_cur = BREATHE_MIN_STEP; -uint8_t breathe_dir = 1; - -static void led_run_pattern(led_setup_t* f, float* ro, float* go, float* bo, float pos) { - float po; - - while (f->end != 1) { - po = pos; // Reset po for new frame - - // Add in any moving effects - if ((!led_animation_direction && f->ef & EF_SCR_R) || (led_animation_direction && (f->ef & EF_SCR_L))) { - po -= pomod; - - if (po > 100) - po -= 100; - else if (po < 0) - po += 100; - } else if ((!led_animation_direction && f->ef & EF_SCR_L) || (led_animation_direction && (f->ef & EF_SCR_R))) { - po += pomod; - - if (po > 100) - po -= 100; - else if (po < 0) - po += 100; - } - - // Check if LED's po is in current frame - if (po < f->hs) { - f++; - continue; - } - if (po > f->he) { - f++; - continue; - } - // note: < 0 or > 100 continue - - // Calculate the po within the start-stop percentage for color blending - po = (po - f->hs) / (f->he - f->hs); - - // Add in any color effects - if (f->ef & EF_OVER) { - *ro = (po * (f->re - f->rs)) + f->rs; // + 0.5; - *go = (po * (f->ge - f->gs)) + f->gs; // + 0.5; - *bo = (po * (f->be - f->bs)) + f->bs; // + 0.5; - } else if (f->ef & EF_SUBTRACT) { - *ro -= (po * (f->re - f->rs)) + f->rs; // + 0.5; - *go -= (po * (f->ge - f->gs)) + f->gs; // + 0.5; - *bo -= (po * (f->be - f->bs)) + f->bs; // + 0.5; - } else { - *ro += (po * (f->re - f->rs)) + f->rs; // + 0.5; - *go += (po * (f->ge - f->gs)) + f->gs; // + 0.5; - *bo += (po * (f->be - f->bs)) + f->bs; // + 0.5; - } - - f++; - } -} - -static void led_matrix_massdrop_config_override(int i) { - float ro = 0; - float go = 0; - float bo = 0; - - float po = (led_animation_orientation) ? (float)g_led_config.point[i].y / 64.f * 100 : (float)g_led_config.point[i].x / 224.f * 100; - - uint8_t highest_active_layer = biton32(layer_state); - - if (led_lighting_mode == LED_MODE_KEYS_ONLY && HAS_FLAGS(g_led_config.flags[i], LED_FLAG_UNDERGLOW)) { - // Do not act on this LED - } else if (led_lighting_mode == LED_MODE_NON_KEYS_ONLY && !HAS_FLAGS(g_led_config.flags[i], LED_FLAG_UNDERGLOW)) { - // Do not act on this LED - } else if (led_lighting_mode == LED_MODE_INDICATORS_ONLY) { - // Do not act on this LED (Only show indicators) - } else { - led_instruction_t* led_cur_instruction = led_instructions; - while (!led_cur_instruction->end) { - // Check if this applies to current layer - if ((led_cur_instruction->flags & LED_FLAG_MATCH_LAYER) && (led_cur_instruction->layer != highest_active_layer)) { - goto next_iter; - } - - // Check if this applies to current index - if (led_cur_instruction->flags & LED_FLAG_MATCH_ID) { - uint8_t modid = i / 32; // Calculate which id# contains the led bit - uint32_t modidbit = 1 << (i % 32); // Calculate the bit within the id# - uint32_t* bitfield = &led_cur_instruction->id0 + modid; // Add modid as offset to id0 address. *bitfield is now idX of the led id - if (~(*bitfield) & modidbit) { // Check if led bit is not set in idX - goto next_iter; - } - } - - if (led_cur_instruction->flags & LED_FLAG_USE_RGB) { - ro = led_cur_instruction->r; - go = led_cur_instruction->g; - bo = led_cur_instruction->b; - } else if (led_cur_instruction->flags & LED_FLAG_USE_PATTERN) { - led_run_pattern(led_setups[led_cur_instruction->pattern_id], &ro, &go, &bo, po); - } else if (led_cur_instruction->flags & LED_FLAG_USE_ROTATE_PATTERN) { - led_run_pattern(led_setups[led_animation_id], &ro, &go, &bo, po); - } - - next_iter: - led_cur_instruction++; - } - - if (ro > 255) - ro = 255; - else if (ro < 0) - ro = 0; - if (go > 255) - go = 255; - else if (go < 0) - go = 0; - if (bo > 255) - bo = 255; - else if (bo < 0) - bo = 0; - - if (led_animation_breathing) { - ro *= breathe_mult; - go *= breathe_mult; - bo *= breathe_mult; - } - } - - led_buffer[i].r = (uint8_t)ro; - led_buffer[i].g = (uint8_t)go; - led_buffer[i].b = (uint8_t)bo; -} - -#endif // USE_MASSDROP_CONFIGURATOR |